/* ============================================================================
   afinar.app — site tokens
   Design commission return, 2026-08-06. Frames F1/F2/F3 are built from this
   file. A value in a frame that is not in this file is a bug, not a decision.

   PROVENANCE — three kinds of value live here, marked on every line:
     [SHIPPING]  transcribed from DESIGN_LANGUAGE.md §4a, itself a verbatim
                 mirror of DualTrack/Appearance.swift. Code is the source; if
                 this disagrees with Appearance.swift, the code is right.
     [BRAND]     SPEC.md §12 (name, palette, type) and §11a (record red).
     [SITE]      derived for this commission. Nothing outside the site depends
                 on these. Every one of them is stated below with its reason.

   THE ONE TRAP, from DESIGN_LANGUAGE §4a: amber changes value between skins.
   Interaction on a light ground is --amber (#8F6A16). The Console amber
   #D4A73A is 1.9:1 on paper and is declared here only so that reaching for it
   is a visible mistake. Do not lighten either amber: §4a records 4.67:1 for
   white on light amber and 3.87:1 for light amber on ivory, neither with
   margin.
   ============================================================================ */

:root {

  /* --- Ground ------------------------------------------------------------ */
  --paper:            #F7F3EB;  /* [SITE] page ground. Warm family, one step
                                   lighter and cleaner than the app's chassis:
                                   §4a says a page is paper, the machine sits
                                   on it, and they should not be the same
                                   surface. Ink on this: 14.9:1. */
  --paper-raised:     #EFEAE0;  /* [SHIPPING] panelBar/Paper. Alternate section
                                   band. The site borrows the app's own second
                                   surface rather than inventing one. */
  --paper-sunk:       #E9E3D5;  /* [SHIPPING] panelChassis/Paper — the app's
                                   ivory. Table headers, card edges: the places
                                   the page is standing in for a device. */

  /* --- Ink --------------------------------------------------------------- */
  --ink:              #1A1815;  /* [SHIPPING] labelPrimary/Paper. 13.9:1 on the
                                   app's ivory, 14.9:1 on --paper. */
  --ink-secondary:    #3A352C;  /* [SHIPPING] labelSecondary/Paper. 9.5:1. Body
                                   copy sits here, not on --ink: a page of
                                   maximum-contrast body text reads as a
                                   document, not a page. */
  --ink-tertiary:     #5C574C;  /* [SHIPPING] labelTertiary/Paper. 5.8:1 — the
                                   contrast floor. Nothing goes below this. */
  --hairline:         #C8C1AF;  /* [SHIPPING] seamWindow + keycapEdge/Paper.
                                   Structure is hairline seams, never a
                                   background-colour change (DESIGN_LANGUAGE
                                   §2, §3 zones ruling). */

  /* --- Signal — one meaning each, no new hues (DESIGN_LANGUAGE §4) -------- */
  --amber:            #8F6A16;  /* [SHIPPING] amberAction/Paper. Interaction and
                                   selection on a light ground: links, the
                                   primary action, the brand mark. */
  --amber-on:         #FBF8F1;  /* [SHIPPING] amberOn/Paper. Text ON an amber
                                   fill. 4.67:1, no margin, do not lighten. */
  --amber-console:    #D4A73A;  /* [BRAND/SHIPPING] amberAction/Console. NEVER
                                   on paper — 1.9:1. Declared so that a frame
                                   using it is visibly wrong. It is correct
                                   inside every app screenshot on the page,
                                   because displays never invert (§11a rule 1). */
  --record-red:       #B8402F;  /* [BRAND] SPEC §11a: the one hex that never
                                   moves, either skin. Recording only. */

  /* --- The deep object --------------------------------------------------- */
  --console:          #0F0E0C;  /* [SHIPPING] panelChassis/Console. The dark app
                                   window is the one deep object on the page. */
  --console-bar:      #131110;  /* [SHIPPING] panelBar/Console. */
  --console-glass:    #0C0B09;  /* [SHIPPING] display glass, both skins. */
  --console-label:    #E6E1D7;  /* [SHIPPING] labelPrimary/Console — type on a
                                   dark band. */

  /* --- Type ---------------------------------------------------------------
     DISPLAY FACE CHANGED 2026-08-06, at Albizu's direction, from a reference
     frame. This overrides SPEC §12's Bricolage Grotesque. It is a BRAND
     ruling, not a site decision: §12 needs amending or this site and the app's
     brand moments will disagree. Body and label faces are unchanged and still
     §12's.
     The reference is a closed-aperture geometric with a high x-height. Poppins
     is the closest face on Google Fonts; if the original is identified later,
     swapping it is one line here and nothing else. -------------------------- */
  --font-display:  'Recoleta', 'Fraunces', Georgia, serif;
  --display-vars:  'SOFT' 44, 'WONK' 1, 'opsz' 96;
  --font-body:     'Hanken Grotesk', 'Helvetica Neue', Helvetica, sans-serif;
  --font-mono:     'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Ramp. Desktop values; the mobile overrides are at the foot of this file.
     Ratio is roughly 1.28, tightened at the top so the hero can be large
     without the H2s having to shout. */
  --type-hero:        70px;   --lh-hero:    1.06;  --track-hero:   -0.012em;
  --type-h2:          42px;   --lh-h2:      1.14;  --track-h2:     -0.008em;
  --type-h3:          26px;   --lh-h3:      1.20;  --track-h3:     -0.012em;
  --type-lead:        22px;   --lh-lead:    1.50;
  --type-body:        19px;   --lh-body:    1.62;
  --type-small:       16px;   --lh-small:   1.55;
  --type-label:       11px;   --lh-label:   1.00;  --track-label:   0.14em;

  --weight-display:   600;    /* Bricolage at 600. 700 reads as a poster. */
  --weight-body:      400;
  --weight-medium:    500;

  /* --- Spacing. 4px base; the only sizes that exist. --------------------- */
  --s1:   4px;   --s2:   8px;   --s3:  12px;   --s4:  16px;
  --s5:  24px;   --s6:  32px;   --s7:  48px;   --s8:  64px;
  --s9:  96px;   --s10:128px;   --s11:160px;   --s12:200px;

  /* --- Layout ------------------------------------------------------------ */
  --page:            1440px;  /* [SITE] the frame width this design is drawn at */
  --content:         1200px;  /* [SITE] 12 columns of 78px, 24px gutters */
  --measure:          660px;  /* [SITE] prose column. ~72 characters at 19px. */
  --gutter:           120px;  /* [SITE] (1440 - 1200) / 2 */
  --col-gap:           24px;
  --nav-h:             72px;

  /* --- Radii. Control radius is the app's own. --------------------------- */
  --r-control:          6px;  /* [SHIPPING] DESIGN_LANGUAGE §4: "radius 6 like
                                 every other control there." */
  --r-shot:            25px;  /* [SITE] the macOS window corner, MEASURED off
                                 13-web-score-songsterr.png: the capture's own
                                 baked corner starts 63px in at 3024 native,
                                 which is 25px at the 1200 display width. Used
                                 only to round the screen RECORDINGS, whose
                                 corners are square because they are full-screen
                                 grabs. The PNG captures already carry theirs and
                                 must never be given a second one. */
  --r-plate:            4px;  /* [SITE] direction plates */

  /* --- Elevation. One shadow. The page has one deep object; it does not
         need a scale of shadows. ---------------------------------------- */
  --shadow-object: 0 48px 88px -32px rgba(26, 24, 21, 0.34),
                   0 8px 24px -12px rgba(26, 24, 21, 0.18);

  /* --- Ink bleed ------------------------------------------------------------
     [SITE] The soft edge from the reference frame. On paper it reads as ink
     spreading very slightly into an uncoated sheet, which is why it is allowed
     here at all: it is a material effect, not a glow. Display type only. Body
     and label type stay crisp, because a blurred paragraph is a legibility
     failure and would breach §6's accessibility-is-material rule. Same hue as
     the ink, so contrast is unchanged: it thickens the stroke, it does not
     wash it. Do not raise the radius. ---------------------------------------- */
  /* WITHDRAWN with the serif. A high-contrast serif has real thick/thin
     modulation, so the faked printed edge is redundant and muddies the thins. */
  --bleed:           none;
  --bleed-light:     none;

  --dur-fade:        220ms;   /* [SITE] the only motion the brief permits
                                 outside the app captures */
  --ease:            cubic-bezier(0.2, 0, 0.2, 1);
}

/* ============================================================================
   COMPONENT SPECS — written as the rules themselves, per the commission.
   The frames use these classes. Nothing below introduces a value that is not
   a token above.
   ============================================================================ */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-secondary);
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: var(--lh-body);
  font-weight: var(--weight-body);
}

/* --- Type ---------------------------------------------------------------- */

h1, h2, h3 {
  font-family: var(--font-display);
  font-variation-settings: var(--display-vars);
  font-weight: var(--weight-display);
  color: var(--ink);
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: var(--type-hero); line-height: var(--lh-hero); letter-spacing: var(--track-hero); text-shadow: var(--bleed); }
h2 { font-size: var(--type-h2);   line-height: var(--lh-h2);   letter-spacing: var(--track-h2); max-width: 880px; text-shadow: var(--bleed); }
h3 { font-size: var(--type-h3);   line-height: var(--lh-h3);   letter-spacing: var(--track-h3); text-shadow: var(--bleed); }

p { margin: 0; text-wrap: pretty; }

.lead { font-size: var(--type-lead); line-height: var(--lh-lead); color: var(--ink-secondary); }
.small { font-size: var(--type-small); line-height: var(--lh-small); }

/* Mono is print on the panel: labels beside things, never inside them
   (DESIGN_LANGUAGE §2 SILKSCREEN). On the site it is confined to the tier
   table's column heads, the footer's legal row, and annotation. It is NOT an
   eyebrow: home.md's structural rulings ban eyebrows outright. */
.mono {
  font-family: var(--font-mono);
  font-size: var(--type-label);
  line-height: var(--lh-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink-tertiary);
}

a { color: var(--amber); text-decoration: none; }
a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

/* --- Layout -------------------------------------------------------------- */

.page { width: var(--page); margin: 0 auto; background: var(--paper); overflow: hidden; }
.wrap { width: var(--content); margin: 0 auto; }
.measure { max-width: var(--measure); }

/* Section anatomy: 160px of air above and below, 96px for a deliberate short
   beat, a hairline only where two ideas need separating. Sections are told
   apart by air and by ground, never by a box. */
.section      { padding: var(--s11) 0; }
.section--short { padding: var(--s9) 0; }
.section--raised { background: var(--paper-raised); }
.section + .section { border-top: 0; }
.rule { height: 1px; background: var(--hairline); border: 0; margin: 0; }

/* Heading + prose block. The heading is the benefit; the paragraph follows at
   the prose measure, never the full column. */
.block > h2 + p,
.block > h2 + .lead { margin-top: var(--s5); }
.block > p + p { margin-top: var(--s4); }

/* --- Nav ----------------------------------------------------------------- */

.nav {
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--hairline);
}
.nav__mark {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: 21px;
  letter-spacing: -0.01em;
  color: var(--ink);
  font-variation-settings: var(--display-vars);
}
.nav__links { display: flex; align-items: center; gap: var(--s6); }
.nav__link {
  font-size: var(--type-small);
  color: var(--ink-secondary);
  display: flex;
  align-items: center;
  gap: var(--s2);
}
.nav__link:hover { color: var(--ink); text-decoration: none; }

/* Features menu. CSS-only so it works in a plain static page with no script.
   The panel is the five feature pages, in the order nav-footer.md fixes.

   THE HOVER REGION IS ONE CONTINUOUS AREA (fixed 2026-08-20). It used to be
   two: the panel sat --s3 below the trigger on its own margin, and a margin is
   not hoverable by anything. Aiming at an item meant crossing 12px of dead
   floor, :hover went false on the way down, and the menu shut before it could
   be reached — reported live by Albizu. The offset is now padding on
   .nav__menu, which IS the hover parent, with a matching negative margin so
   the strip's layout is unchanged and the panel lands on the same pixel.
   Nothing here may reintroduce a margin, a gap, or a transform between the
   trigger and the panel. */
.nav__menu {
  position: relative;
  display: flex;
  align-items: center;
  padding: var(--s3) 0;
  margin: calc(var(--s3) * -1) 0;
}
.nav__menu > .nav__link { cursor: default; }
.nav__panel {
  position: absolute;
  top: 100%;
  left: calc(var(--s5) * -1);
  min-width: 210px;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--r-control);
  box-shadow: 0 20px 40px -16px rgba(26, 24, 21, 0.24);
  padding: var(--s3) 0;
  display: flex;
  flex-direction: column;
  z-index: 10;
  /* Closed. It opens instantly and closes on a 180ms grace, so a pointer that
     clips a corner on its way to an item does not lose the menu. Re-entering
     inside the grace cancels it outright — the open rule's 0s delays win the
     moment :hover is true again. visibility, not display, because display
     cannot be waited on; hidden also keeps the links out of the tab order,
     which is what makes :focus-within open it rather than fight it. */
  opacity: 0;
  visibility: hidden;
  transition: opacity 140ms var(--ease) 180ms, visibility 0s linear 320ms;
}
.nav__menu:hover .nav__panel,
.nav__menu:focus-within .nav__panel {
  opacity: 1;
  visibility: visible;
  transition: opacity 90ms var(--ease) 0s, visibility 0s linear 0s;
}
@media (prefers-reduced-motion: reduce) {
  .nav__panel,
  .nav__menu:hover .nav__panel,
  .nav__menu:focus-within .nav__panel { transition-duration: 0s; }
}
.nav__panel a {
  font-size: var(--type-small);
  color: var(--ink-secondary);
  padding: var(--s2) var(--s5);
}
.nav__panel a:hover { color: var(--ink); background: var(--paper-raised); text-decoration: none; }

/* --- Format picker -------------------------------------------------------
   A stepped viewer, not a carousel: nothing advances on its own, and every
   option is addressable so a reader goes straight to their own case instead
   of waiting for it. Radio + :checked so it works in a static page with no
   script. The stage is 800px because below ~560 the app's silkscreen stops
   being legible and the capture becomes decoration.
   ------------------------------------------------------------------------- */

.picker { margin-top: var(--s8); }
.picker__radio { position: absolute; opacity: 0; pointer-events: none; }
.picker__body { display: grid; grid-template-columns: 340px 1fr; gap: var(--s9); align-items: start; }
.picker__rail { display: flex; flex-direction: column; }
.picker__opt {
  display: block;
  font-family: var(--font-body);
  font-size: var(--type-lead);
  line-height: 1.3;
  color: var(--ink-tertiary);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--hairline);
  cursor: pointer;
  transition: color var(--dur-fade) var(--ease);
}
.picker__opt:first-child { border-top: 1px solid var(--hairline); }
.picker__opt:hover { color: var(--ink-secondary); }
.picker__desc { display: none; font-size: var(--type-small); line-height: 1.6; color: var(--ink-secondary); padding: var(--s4) 0 0; }
.picker__panel { display: none; }
.picker__stage figure { margin: 0; }
/* Captures come in two window ratios (3024×1898 and 3164×2038). Pin the box to
   the taller one and anchor the top, so every window's top and side edges land
   in the same place as tabs change; only the bottom edge varies, by 12px, on
   the three older captures. */
.picker__stage figure > a { display: block; aspect-ratio: 3164 / 2038; }
.picker__stage figure > a > img { width: 100%; height: 100%; object-fit: contain; object-position: top; }
.picker__figcap { font-size: var(--type-small); color: var(--ink-tertiary); margin-top: var(--s4); display: flex; align-items: center; gap: var(--s3); }
.picker__zoom { color: var(--amber); }

.picker__radio:focus-visible + .picker__body .picker__opt { outline: none; }

#fmt-1:checked ~ .picker__body [for="fmt-1"],
#fmt-2:checked ~ .picker__body [for="fmt-2"],
#fmt-3:checked ~ .picker__body [for="fmt-3"],
#fmt-4:checked ~ .picker__body [for="fmt-4"],
#fmt-5:checked ~ .picker__body [for="fmt-5"],
#fmt-6:checked ~ .picker__body [for="fmt-6"] { color: var(--ink); font-weight: var(--weight-medium); }

#fmt-1:checked ~ .picker__body .picker__desc--1,
#fmt-2:checked ~ .picker__body .picker__desc--2,
#fmt-3:checked ~ .picker__body .picker__desc--3,
#fmt-4:checked ~ .picker__body .picker__desc--4,
#fmt-5:checked ~ .picker__body .picker__desc--5,
#fmt-6:checked ~ .picker__body .picker__desc--6,
#fmt-1:checked ~ .picker__body .picker__panel--1,
#fmt-2:checked ~ .picker__body .picker__panel--2,
#fmt-3:checked ~ .picker__body .picker__panel--3,
#fmt-4:checked ~ .picker__body .picker__panel--4,
#fmt-5:checked ~ .picker__body .picker__panel--5,
#fmt-6:checked ~ .picker__body .picker__panel--6 { display: block; }

/* Enlarge. :target overlay, so it needs no script and closing is a link. */
.lightbox {
  position: fixed;
  inset: 0;
  background: rgba(26, 24, 21, 0.88);
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--s7);
  z-index: 100;
}
.lightbox:target { display: flex; }
.lightbox__dismiss { position: absolute; inset: 0; }
.lightbox img { position: relative; max-width: 100%; max-height: 100%; height: auto; border-radius: var(--r-shot); }

/* --- Buttons. One primary action per view; everything else is a link.
       The keycap: flat rounded rect, 1px edge, pressed = darken + 1px down
       (DESIGN_LANGUAGE §3). ------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-size: var(--type-small);
  font-weight: var(--weight-medium);
  border-radius: var(--r-control);
  border: 1px solid transparent;
  padding: var(--s3) var(--s5);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-fade) var(--ease), transform var(--dur-fade) var(--ease);
}
/* The primary action is INK, not amber. --amber (#8F6A16) is shipping code and
   cannot be lightened — DESIGN_LANGUAGE §4a records white-on-amber at 4.67:1
   with no margin — but at button size that low-chroma gold reads olive. Small
   amber areas (links, the mark, table ticks) are fine; a large flat fill is
   not. Ink is 14.9:1 on paper, matches the one deep object on the page, and
   hands amber back to the hover state so it keeps its meaning. */
.btn--primary { background: var(--ink); color: var(--paper); }
.btn--primary:hover { background: var(--amber); color: var(--amber-on); text-decoration: none; }
.btn--primary:active { transform: translateY(1px); }
.btn--lg { font-size: var(--type-lead); padding: var(--s4) var(--s7); }
.btn--quiet { background: transparent; color: var(--ink); border-color: var(--hairline); }

/* The state a control is in when the thing behind it does not exist yet.
   RULED 2026-08-20 (Albizu): every download CTA reads `Coming Soon` until
   there is a build. Same keycap, same size, same place — no fill, hairline
   edge, tertiary ink at 5.8:1, and no hover or press, because nothing
   happens. It is the shape of the action with the action taken out.
   Carried on a <span role="button" aria-disabled="true">: not a link, not
   focusable, and never href="#". This is NOT the dashed-amber placeholder
   idiom — that marked things that must not ship; this one ships. */
.btn--soon {
  background: none;
  color: var(--ink-tertiary);
  border-color: var(--hairline);
  cursor: default;
}

/* --- Screenshot framing --------------------------------------------------
   Captures are 3024x1898 window grabs with their own rounded corners and
   transparent corner pixels. Do NOT clip them or add a border: that draws a
   second corner inside the real one. Elevation is a drop-shadow filter, which
   follows the alpha, not a box-shadow, which would square it off.
   Display width 1200 (full column) or 840 (inset). Never smaller than 560 —
   below that the rail's silkscreen stops being legible and the shot is
   decoration. -------------------------------------------------------------- */

.shot { display: block; width: 100%; height: auto; filter: drop-shadow(0 48px 68px rgba(26, 24, 21, 0.30)); }
.shot--inset { width: 840px; }

/* --- Direction plate — DELIBERATELY ABSENT FROM THE SHIPPING STYLESHEET -----
   The dashed-amber `.plate` is the design return's ANNOTATION idiom: image
   direction and notes-to-the-builder, carried inside the frame so copy and
   image were chosen together (BRIEF-marketing-handoff §7). Its own header
   says it does not ship — and on 2026-08-20 five of them shipped anyway,
   transcribed straight out of the frames onto /auto-scroll/, /changelog/,
   /press/, /help/ and /help/auto-scroll/. A journalist on /press/ read
   `ASSET ZIP · DOES NOT EXIST YET`.

   The rules live on in docs/design-returns/tokens.css, which is where the
   frames load their CSS from and where the annotation belongs. They are gone
   from here so this stylesheet CANNOT draw one: if a plate is ever
   transcribed again it lands unstyled and obvious instead of arriving
   looking deliberate. Do not restore them. Delete the .plate element and
   drop the real asset in its place, exactly as the frame headers instruct.
   -------------------------------------------------------------------- */

/* --- Tier table. The most-quoted table on a product site (rebuild §5), so it
       is real semantic markup, left-aligned, no zebra, hairlines only. ----- */

.tier-table { width: 100%; border-collapse: collapse; font-size: var(--type-small); }
.tier-table th, .tier-table td { text-align: left; padding: var(--s4) var(--s5); border-bottom: 1px solid var(--hairline); }
.tier-table thead th { background: var(--paper-sunk); color: var(--ink); font-family: var(--font-mono); font-size: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; font-weight: var(--weight-medium); }
.tier-table td:nth-child(2), .tier-table td:nth-child(3),
.tier-table th:nth-child(2), .tier-table th:nth-child(3) { width: 128px; text-align: center; }
.tier-table .yes { color: var(--amber); }
.tier-table .no  { color: var(--ink-tertiary); }

/* --- Footer -------------------------------------------------------------- */

.footer { background: var(--paper-raised); border-top: 1px solid var(--hairline); padding: var(--s9) 0 var(--s7); }
.footer__cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s7); }
.footer__col { display: flex; flex-direction: column; gap: var(--s3); }
.footer__head { font-family: var(--font-mono); font-size: var(--type-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-tertiary); margin-bottom: var(--s2); }
.footer a { color: var(--ink-secondary); font-size: var(--type-small); }
.footer a:hover { color: var(--ink); }
.footer__legal { display: flex; justify-content: space-between; align-items: baseline; margin-top: var(--s8); padding-top: var(--s5); border-top: 1px solid var(--hairline); color: var(--ink-tertiary); font-size: var(--type-small); }

/* ============================================================================
   MOBILE — 390. The strip in F3-mobile.png is drawn at these values.
   ============================================================================ */

@media (max-width: 480px) {
  :root {
    --type-hero:  38px;  --track-hero: -0.018em;
    --type-h2:    29px;
    --type-h3:    22px;
    --type-lead:  19px;
    --type-body:  17px;
    --page:      390px;
    --content:   350px;
    --gutter:     20px;
    --nav-h:      56px;
  }
  .section { padding: var(--s8) 0; }
  .section--short { padding: var(--s7) 0; }
  .footer__cols { grid-template-columns: repeat(2, 1fr); gap: var(--s6); }
}
