/* ==========================================================================
   ShopFront — Secondary-page chrome
   --------------------------------------------------------------------------
   Shared by every page that is not the catalogue: about.html, faq.html,
   contact.html and login.html — the last of which takes only the
   breadcrumb. It holds the parts those pages have in common — the
   breadcrumb, the gradient page hero, the sticky in-page nav, the media
   placeholders, the closing CTA band, and two button/badge variants — so
   none of them re-implements another's chrome.

   Load order is `tokens.css → styles.css → page.css → <page>.css`. Nothing
   here overrides styles.css; it only adds what styles.css does not carry.

   The house rules from styles.css apply unchanged:
     · The design is flat. Surfaces separate by border and tone, never by
       shade. The --shadow-* ramp resolves to none — the calls are kept so
       that turning elevation back on stays a one-line edit in tokens.css.
     · Logical properties only (inline/block): the document is RTL and
       every one of these blocks has to mirror.
     · No raw colour, no raw shadow, no off-grid spacing. Tokens only.

   Contents
     01 · SHARED BUTTON & BADGE VARIANTS
     02 · MEDIA PLACEHOLDERS
     03 · BREADCRUMB
     04 · PAGE HERO
     05 · PAGE NAV
     06 · CTA BAND
     07 · RESPONSIVE
     08 · MOTION, CONTRAST, PRINT
   ========================================================================== */


/* ==========================================================================
   01 · SHARED BUTTON & BADGE VARIANTS
   --------------------------------------------------------------------------
   Modifiers these pages need that styles.css does not carry yet. They are
   written against the shared .btn / .badge bases rather than as page-local
   classes, so they can move to sections 04 and 05 of styles.css unchanged
   the day the catalogue wants them too.
   ========================================================================== */

/* Outline pill for a saturated field, beside the solid .btn--onbrand. Two
   CTAs on one panel need different weights or they compete; this is the
   secondary of the pair. The fill is a black wash rather than a white one:
   white at any opacity lifts the panel toward the 4.5:1 floor that the
   white label above it depends on. */
.btn--ghost-onbrand {
  border: var(--border-thin) solid var(--border-inverse);
  background: oklch(0 0 0 / 0.14);
  color: var(--fg-on-brand);
}
.btn--ghost-onbrand:hover {
  transform: translateY(-3px);
  border-color: oklch(1 0 0 / 0.42);
  background: oklch(0 0 0 / 0.24);
}
.btn--ghost-onbrand:active {
  transform: translateY(-1px);
}

/* Quiet badge, for a label that qualifies something rather than alerting
   about it — the opposite end of the scale from .badge--discount. */
.badge--soft {
  padding: var(--space-1-5) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
}
.badge--soft .icon {
  font-size: var(--icon-sm);
}

/* On a saturated or dark panel the subtle teal wash disappears; this swaps
   it for the same translucent treatment the panel's own eyebrow uses.
   Stack it on .badge--soft rather than nesting a descendant selector, so a
   badge is styled by what it is and not by what it happens to sit inside. */
.badge--onpanel {
  border: var(--border-hairline) solid var(--border-inverse);
  background: oklch(0 0 0 / 0.18);
  color: inherit;
}


/* ==========================================================================
   02 · MEDIA PLACEHOLDERS
   --------------------------------------------------------------------------
   Every picture on this page is deliberately empty: the artwork is
   commissioned separately and dropped in later. A missing <img src> would
   render as a broken-image glyph and collapse the layout it was holding
   open, so each slot is a real element instead — it reserves the exact box
   the final image will occupy, states what belongs there, and prints the
   intended pixel size so the shot can be briefed from the page itself.

   To fill one, replace the .ph__frame element with:
     <img src="assets/about/xxx.jpg" alt="…" width="…" height="…"
          loading="lazy" decoding="async">
   and keep the surrounding <figure class="ph"> — every aspect-ratio
   modifier lives on the figure, not on the frame.
   ========================================================================== */

.ph {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-2-5);
  min-inline-size: 0;
}

/* The frame and a real <img> are interchangeable: both fill the figure and
   both take the same rounding, so swapping one for the other cannot shift
   the layout by a pixel. */
.ph__frame,
.ph > img {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-2);
  inline-size: 100%;
  block-size: 100%;
  min-block-size: 11rem;
  padding: var(--space-6);
  border-radius: var(--radius-2xl);
  object-fit: cover;
}

.ph__frame {
  /* Dashed, not solid: it has to read as "pending" at a glance rather than
     as a finished bordered card. */
  border: var(--border-thin) dashed var(--border-strong);
  background:
    repeating-linear-gradient(
      135deg,
      transparent 0 var(--space-4),
      var(--bg-surface-2) var(--space-4) calc(var(--space-4) * 2)),
    var(--bg-surface);
  color: var(--fg-subtle);
  text-align: center;
  transition: var(--transition-colors);
}
.ph:hover .ph__frame {
  border-color: var(--border-brand);
  color: var(--brand-text);
}

.ph__frame .icon {
  color: var(--brand);
  opacity: 0.75;
}

.ph__label {
  color: var(--fg-body);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

.ph__hint {
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--bg-inset);
  color: var(--fg-subtle);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  /* The dimensions are Latin digits inside an RTL paragraph; without an
     explicit direction the × lands on the wrong side of the pair. */
  direction: ltr;
}

.ph__cap {
  color: var(--fg-subtle);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}

/* Aspect modifiers. Ratio rather than a fixed height, so a slot keeps its
   proportions at every breakpoint and the final image can be cropped to a
   number that is written down.

   The ratio is applied to the frame, not to the figure. On the figure it
   would count the caption as part of the box — the frame would shrink by
   the height of its own caption, and a caption that overflowed would sit
   on top of whatever came next. */
.ph--wide     > .ph__frame, .ph--wide     > img { aspect-ratio: 16 / 9; }
.ph--banner   > .ph__frame, .ph--banner   > img { aspect-ratio: 24 / 7; }
.ph--square   > .ph__frame, .ph--square   > img { aspect-ratio: 1; }
.ph--portrait > .ph__frame, .ph--portrait > img { aspect-ratio: 3 / 4; }
.ph--tall     > .ph__frame, .ph--tall     > img { aspect-ratio: 4 / 5; }

/* Circular slot, for a face. */
.ph--avatar {
  inline-size: var(--space-20);
  block-size: var(--space-20);
}
.ph--avatar .ph__frame {
  min-block-size: 0;
  padding: var(--space-2);
  border-radius: var(--radius-circle);
}

/* Placed on a saturated panel, where the page-surface fill would glare. */
.ph--onbrand .ph__frame {
  border-color: var(--border-inverse);
  background: oklch(0 0 0 / 0.14);
  color: inherit;
}
.ph--onbrand .ph__label,
.ph--onbrand .ph__frame .icon {
  color: inherit;
}
.ph--onbrand .ph__hint {
  background: oklch(0 0 0 / 0.22);
  color: inherit;
}


/* ==========================================================================
   03 · BREADCRUMB
   ========================================================================== */

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-inline-md);
  margin-block-start: var(--space-6);
  padding: var(--space-3) var(--space-5);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--bg-surface);
  color: var(--fg-muted);
  font-size: var(--text-sm);
}

.breadcrumb__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-inline-sm);
  list-style: none;
}

.breadcrumb__item {
  display: flex;
  align-items: center;
  gap: var(--gap-inline-sm);
}

/* Chevron drawn with a pseudo-element rather than a glyph, so it mirrors
   with the writing direction instead of pointing the wrong way in RTL. */
.breadcrumb__item + .breadcrumb__item::before {
  content: "";
  inline-size: var(--space-1-5);
  block-size: var(--space-1-5);
  border-inline-start: var(--border-thin) solid var(--border-strong);
  border-block-end: var(--border-thin) solid var(--border-strong);
  rotate: 45deg;
}

.breadcrumb__item a {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--fg-muted);
  transition: var(--transition-colors);
}
.breadcrumb__item a:hover {
  color: var(--brand-text);
}

.breadcrumb__item [aria-current] {
  color: var(--fg-default);
  font-weight: var(--weight-bold);
}

.breadcrumb__back {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-xs);
  color: var(--brand-text);
  font-weight: var(--weight-bold);
  white-space: nowrap;
}
.breadcrumb__back:hover {
  text-decoration: underline;
  text-underline-offset: 0.25em;
}


/* ==========================================================================
   04 · PAGE HERO
   --------------------------------------------------------------------------
   Copy on the inline-start half, artwork on the other. The panel carries
   the brand gradient, so everything inside it is white-on-teal and takes
   --fg-on-brand; the tokens guarantee no gradient stop lighter than
   teal-600, which is what keeps that text above 4.5:1.
   ========================================================================== */

.page-hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: center;
  gap: var(--space-12);
  margin-block-start: var(--space-6);
  padding: var(--space-14) var(--space-12);
  border-radius: var(--radius-4xl);
  background: var(--gradient-brand);
  color: var(--fg-on-brand);
  overflow: hidden;
}

/* Faint glow so a panel this large does not read as a dead fill. Anchored
   over the artwork column, never behind the copy — a white glow under
   white text costs about 0.4:1. */
.page-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--glow-brand);
  pointer-events: none;
}

.page-hero > * {
  position: relative;
}

.page-hero__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-5);
  min-inline-size: 0;
}

.page-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  padding: var(--space-1-5) var(--space-4);
  border: var(--border-hairline) solid var(--border-inverse);
  border-radius: var(--radius-pill);
  background: oklch(0 0 0 / 0.16);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
}

.page-hero__title {
  color: inherit;
  font-size: var(--text-6xl);
  font-weight: var(--weight-black);
  line-height: var(--leading-tight);
}

.page-hero__lede {
  max-inline-size: 46ch;
  color: inherit;
  opacity: 0.92;
  font-size: var(--text-2xl);
  line-height: var(--leading-normal);
}

.page-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-inline-md);
  margin-block-start: var(--space-2);
}

/* Three facts under the copy, divided by hairlines rather than by cards —
   a card inside a saturated panel reads as a second surface and fights the
   panel it sits on. */
.page-hero__facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
  inline-size: 100%;
  margin-block-start: var(--space-6);
  padding-block-start: var(--space-6);
  border-block-start: var(--border-hairline) solid var(--border-inverse);
}

.page-hero__fact b {
  display: block;
  font-size: var(--text-4xl);
  font-weight: var(--weight-black);
  line-height: var(--leading-none);
}

.page-hero__fact span {
  display: block;
  margin-block-start: var(--space-1-5);
  opacity: 0.82;
  font-size: var(--text-sm);
}

.page-hero__media {
  min-inline-size: 0;
}


/* ==========================================================================
   05 · PAGE NAV
   --------------------------------------------------------------------------
   The page is long. A sticky chip rail gives every section a one-tap
   destination and doubles as a table of contents. It sticks below the site
   header, so its offset is the compact header height plus a hair.
   ========================================================================== */

/* An author `display` beats the UA's `[hidden] { display: none }`, and the
   help centre hides this rail while a search filter is active. */
.page-nav[hidden] {
  display: none;
}

.page-nav {
  position: sticky;
  z-index: var(--z-raised);
  inset-block-start: calc(var(--header-height-compact) + var(--space-2));
  display: flex;
  gap: var(--space-2);
  margin-block-start: var(--space-8);
  padding: var(--space-2);
  border: var(--border-hairline) solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--header-bg-scrolled);
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-width: none;
}
.page-nav::-webkit-scrollbar {
  display: none;
}

@supports (backdrop-filter: blur(1px)) {
  .page-nav {
    backdrop-filter: blur(var(--header-blur)) saturate(160%);
  }
}

.page-nav a {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-inline-sm);
  flex: none;
  padding: var(--space-2-5) var(--space-4);
  border-radius: var(--radius-pill);
  color: var(--fg-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  white-space: nowrap;
  transition: var(--transition-colors);
}
.page-nav a:hover {
  background: var(--bg-brand-subtle);
  color: var(--brand-text);
}
.page-nav a .icon {
  color: var(--brand);
  font-size: var(--icon-sm);
}

/* Anchor targets must clear the sticky header and the chip rail, or the
   heading lands underneath both. */
.catalog > section[id] {
  scroll-margin-block-start: calc(var(--header-height-compact) + var(--space-16));
}


/* ==========================================================================
   06 · CTA BAND
   ========================================================================== */

.cta-band {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  padding: var(--space-10) var(--space-12);
  border-radius: var(--radius-4xl);
  background: var(--gradient-brand);
  color: var(--fg-on-brand);
}

.cta-band__copy {
  min-inline-size: 0;
}

.cta-band__title {
  color: inherit;
  font-size: var(--text-4xl);
  font-weight: var(--weight-black);
}

.cta-band__text {
  margin-block-start: var(--space-2);
  color: inherit;
  opacity: 0.88;
  font-size: var(--text-lg);
}

.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-inline-md);
}


/* ==========================================================================
   07 · RESPONSIVE
   --------------------------------------------------------------------------
   The same four breakpoints styles.css uses. Nothing new is introduced;
   this chrome reflows on the widths the rest of the site already reflows on.
   ========================================================================== */

@media (max-width: 1240px) {
  .page-hero {
    padding: var(--space-12) var(--space-8);
    gap: var(--space-8);
  }
}

@media (max-width: 1150px) {
  /* The artwork column drops under the copy — and goes above it, because a
     screen that has already lost the two-column layout is a screen where
     the picture is the faster orientation cue. */
  .page-hero { grid-template-columns: minmax(0, 1fr); }
  .page-hero__media { order: -1; }
}

@media (max-width: 800px) {
  .page-hero {
    padding: var(--space-8) var(--space-6);
    border-radius: var(--radius-3xl);
  }
  .page-hero__title { font-size: var(--text-5xl); }
  .page-hero__lede { font-size: var(--text-xl); }
  /* One CTA per row: two pills side by side on a phone leave each about
     nine characters before the label is clipped. */
  .page-hero__actions .btn,
  .cta-band__actions .btn { flex: 1 1 100%; }

  .page-nav { margin-block-start: var(--space-6); }

  .cta-band {
    padding: var(--space-8) var(--space-6);
    border-radius: var(--radius-3xl);
  }
}

@media (max-width: 540px) {
  .page-hero__facts {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
  }
  /* Stacked, the three facts read better as label-beside-figure lines than
     as three centred blocks. */
  .page-hero__fact {
    display: flex;
    align-items: baseline;
    gap: var(--gap-inline-md);
  }
  .page-hero__fact span { margin-block-start: 0; }

  .breadcrumb { border-radius: var(--radius-xl); }
  .breadcrumb__back { display: none; }
}


/* ==========================================================================
   08 · MOTION, CONTRAST, PRINT
   ========================================================================== */

@media (prefers-contrast: more) {
  .ph__frame {
    border-color: var(--fg-muted);
  }
}

@media print {
  .page-nav,
  .page-hero__actions,
  .cta-band__actions,
  .breadcrumb__back {
    display: none;
  }
  .page-hero,
  .cta-band {
    background: none;
    color: #000;
    border: 1px solid #000;
  }
}
