/* ==========================================================================
   Avenue Growth Design System — deployable stylesheet
   Imported from the "Avenue Growth Design System" Claude Design project
   (tokens/colors, tokens/typography, tokens/spacing, tokens/shape, base
   components) and assembled into one self-contained file for the static site.
   The Google Fonts @import must remain the first statement in the file.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Jost:wght@500;600&display=swap');

/* ==========================================================================
   Color tokens
   Navy + white carry 70-80% of any page. Blue is structure (10-15%).
   Green is a signal, not a surface — never a background, never decorative.
   ========================================================================== */
:root {
  --color-navy:        #0C2340;
  --color-navy-700:    #16324f;
  --color-blue:        #236192;
  --color-green:       #78BE20;
  --color-green-dark:  #5c9418;
  --color-gray:        #9EA2A2;
  --color-paragraph:   #696969;
  --color-white:       #FFFFFF;
  --color-black:       #000000;

  --surface-page:       var(--color-white);
  --surface-page-dark:  var(--color-navy);
  --surface-card:       var(--color-white);
  --surface-card-dark:  var(--color-navy-700);
  --surface-raised:     var(--color-white);

  --text-heading:         var(--color-navy);
  --text-heading-inverse: var(--color-white);
  --text-ink:             var(--color-navy);  /* default body text color (renamed from --text-body to avoid colliding with the --text-body type-size token) */
  --text-body-muted:      var(--color-paragraph);
  --text-body-inverse:    rgb(255 255 255 / 0.92);
  --text-body-inverse-muted: rgb(255 255 255 / 0.7);
  --text-link:            var(--color-blue);
  --text-link-hover:      var(--color-navy);

  --border-default:  rgb(158 162 162 / 0.30);
  --border-strong:   var(--color-gray);
  --border-inverse:  rgb(255 255 255 / 0.30);

  --accent-signal:    var(--color-green);
  --accent-structure: var(--color-blue);

  --focus-ring: var(--color-blue);

  --state-hover-opacity: 0.9;
  --state-press-scale: 0.98;
  --state-disabled-opacity: 0.45;
}

a { color: var(--text-link); }
a:hover { color: var(--text-link-hover); }
.section--navy a { color: var(--color-white); }
.section--navy a:hover { color: var(--color-green); }

/* ==========================================================================
   Typography tokens
   Inter for ALL live text. Jost is a Google Fonts stand-in for Sackers Gothic
   (the brand logo typeface); swap in real Sackers Gothic webfonts if licensed.
   Personality comes from scale contrast, not decorative type.
   ========================================================================== */
:root {
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: 'Jost', 'Century Gothic', var(--font-body);

  --text-hero:    clamp(38px, 5vw, 60px);
  --text-section: clamp(30px, 3.5vw, 42px);
  --text-sub:     clamp(20px, 2vw, 26px);
  --text-body-lg: 19px;
  --text-body:    17px;
  --text-eyebrow: 12px;
  --text-button:  15px;
  --text-caption: 14px;
  --text-micro:   13px;

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  --leading-heading: 1.25;
  --leading-body:    1.65;
  --tracking-eyebrow: 0.1em;
  --measure-body:    65ch;
}

body {
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: var(--leading-heading); margin: 0 0 var(--space-md); font-family: var(--font-body); }
h1, h2 { font-family: var(--font-display); letter-spacing: 0.01em; }
h1 { font-size: var(--text-hero);    font-weight: var(--weight-semibold); }
h2 { font-size: var(--text-section); font-weight: var(--weight-medium); }
h3 { font-size: var(--text-sub);     font-weight: var(--weight-semibold); }

.text-display { font-family: var(--font-display); letter-spacing: 0.01em; }
p  { max-width: var(--measure-body); margin: 0 0 var(--space-sm); }

.eyebrow {
  font-size: var(--text-eyebrow);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--accent-structure);
  display: block;
  margin-bottom: var(--space-sm);
}
.section--navy .eyebrow { color: var(--accent-signal); }

.text-lede    { font-size: var(--text-body-lg); color: var(--text-body-muted); }
.text-muted   { color: var(--text-body-muted); }
.text-caption { font-size: var(--text-caption); color: var(--text-body-muted); }

/* ==========================================================================
   Spacing & layout tokens
   8px base grid. Every spacing value is a multiple of 8.
   ========================================================================== */
:root {
  --space-xs:  8px;
  --space-sm:  16px;
  --space-md:  24px;
  --space-lg:  40px;
  --space-xl:  88px;
  --space-2xl: 128px;

  --content-max:        1200px;
  --content-max-narrow: 720px;
  --page-pad-desktop:   80px;
  --page-pad-mobile:    24px;
}

.container {
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--page-pad-desktop);
}
.container--narrow { max-width: var(--content-max-narrow); }

@media (max-width: 768px) {
  .container { padding-inline: var(--page-pad-mobile); }
  :root {
    --space-xl: 56px;
    --space-2xl: 72px;
  }
}

.section       { padding-block: var(--space-xl); }
.section--hero { padding-block: var(--space-2xl); }

.section--navy  { background: var(--surface-page-dark); color: var(--text-body-inverse); }
.section--navy h1, .section--navy h2, .section--navy h3 { color: var(--text-heading-inverse); }
.section--navy p { color: var(--text-body-inverse); }
.section--navy .muted { color: var(--text-body-inverse-muted); }

.section--white { background: var(--surface-page); color: var(--text-ink); }
.section--white .muted { color: var(--text-body-muted); }

.row   { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }
.stack { display: flex; flex-direction: column; gap: var(--space-sm); }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--space-md); }

/* ==========================================================================
   Shape, elevation & motion tokens
   Flat design. No shadows, no gradients, no blur. Borders and whitespace
   do the separating. Motion is minimal.
   ========================================================================== */
:root {
  --radius-button: 6px;
  --radius-card:   10px;
  --radius-input:  6px;
  --radius-pill:   999px;

  --border-card:  1px solid var(--border-default);
  --border-input: 1px solid var(--border-strong);

  --motion-fast: 120ms;
  --motion-base: 180ms;
  --motion-ease: ease;
  --motion-reveal: 400ms;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* ==========================================================================
   Base component styles (Buttons, Cards, Badges, Accordion)
   ========================================================================== */
body { background: var(--surface-page); margin: 0; color: var(--text-ink); }

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-body);
  font-size: var(--text-button);
  font-weight: var(--weight-semibold);
  border-radius: var(--radius-button);
  padding: 14px 28px;
  text-decoration: none;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition: opacity var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease), transform var(--motion-fast) var(--motion-ease);
}
.btn:active { transform: scale(var(--state-press-scale)); }
.btn-sm { padding: 9px 18px; font-size: var(--text-caption); }
.btn[disabled] { opacity: var(--state-disabled-opacity); cursor: not-allowed; pointer-events: none; }

/* NAVY LABEL, NOT WHITE, and the green is untouched. Changed 2026-08-23 by
   Brian's decision, out of the design system pass.

   White on #78BE20 measures 2.29:1 against a 4.5:1 readable floor. It was the
   last contrast failure left on any surface after that pass. Four options were
   rendered against this stylesheet: navy on the unchanged green is 6.91:1 and
   is the ONLY one that clears the floor without changing the brand colour.
   White on --color-green-dark is 3.68:1 and still fails, navy on it is 4.29:1
   and still fails, and darkening green until white works turns it olive.

   So the fill is exactly the green it always was. Only the words on it moved. */
.btn-primary   { background: var(--accent-signal); color: var(--color-navy); }
.btn-primary:hover { opacity: var(--state-hover-opacity); color: var(--color-navy); }

/* A BUTTON IS NOT A LINK, and the link rules near the top of this file were
   treating it as one. `.section--navy a` is specificity (0,1,1) and beats
   `.btn-primary` at (0,1,0), so ON A NAVY SECTION THE PRIMARY BUTTON NEVER
   TOOK ITS OWN LABEL COLOUR AT ALL. It was white because of the link rule, and
   changing .btn-primary above would have done nothing to the homepage hero.

   Worse, and this one was live on production: `.section--navy a:hover` is
   (0,2,1) and beats `.btn-primary:hover` at (0,2,0), so hovering the green
   button set its label to GREEN ON A GREEN FILL. The label vanished on hover.

   .btn-ghost and .btn-secondary are deliberately NOT included here. Ghost is
   transparent with a white label on navy, which is what the link rule happens
   to give it, and secondary never appears on a navy section. Adding them would
   be fixing something nothing is asking for. */
.section--navy .btn-primary,
.section--navy .btn-primary:hover { color: var(--color-navy); }


.btn-secondary { background: transparent; color: var(--color-navy); border-color: var(--border-strong); }
.btn-secondary:hover { border-color: var(--color-navy); color: var(--color-navy); }

.btn-ghost { background: transparent; color: var(--color-white); border-color: var(--border-inverse); }
.btn-ghost:hover { border-color: var(--color-white); color: var(--color-white); }

/* ---- Cards ---- */
.card {
  background: var(--surface-card);
  border: var(--border-card);
  border-radius: var(--radius-card);
  padding: var(--space-md);
}
.card h3 { color: var(--text-heading); }
.card p  { color: var(--text-body-muted); margin-bottom: 0; }

/* ---- Badges / tier pills ---- */
.badge {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-micro);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
  border-radius: var(--radius-pill);
  padding: 4px 12px;
  border: 1px solid transparent;
  align-self: flex-start;
}
.badge-newsletter { background: transparent; border-color: var(--border-strong); color: var(--text-body-muted); }
.badge-operator   { background: rgb(35 97 146 / 0.10); color: var(--color-blue); }
.badge-executive  { background: rgb(120 190 32 / 0.12); color: #4d7a15; }
.badge-paid       { background: rgb(120 190 32 / 0.12); color: #4d7a15; }

/* ---- Accordion ---- */
.accordion-item { border-bottom: 1px solid var(--border-default); }
.accordion-trigger {
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  font-family: var(--font-body); font-size: var(--text-body); font-weight: var(--weight-medium); color: var(--text-ink);
  padding: var(--space-sm) 0; display: flex; justify-content: space-between; align-items: center; gap: var(--space-sm);
  list-style: none;
}
.accordion-trigger::-webkit-details-marker { display: none; }
.accordion-trigger .accordion-icon { color: var(--color-blue); font-size: 20px; line-height: 1; transition: transform var(--motion-base) var(--motion-ease); }
.accordion-item[open] .accordion-trigger .accordion-icon { transform: rotate(45deg); }
.accordion-panel { padding-bottom: var(--space-sm); color: var(--text-body-muted); }
.accordion-panel p { margin-bottom: 0; }

/* ==========================================================================
   PRODUCT-ONLY STATUS TOKENS — do not use on a marketing page
   ==========================================================================
   Added 2026-08-20 for the portal rebuild. Settled as (status-palette) in
   OPERATIONS.md: option A, the warm and cool split, chosen after three
   strategies were rendered at product scale on real queue rows and on the navy
   rail rather than as swatches.

   THE CONTAINING RULE, which is the whole reason this is a fence:
     - Green is only ever a CTA fill, or the dot on a ready chip.
       Never a status fill. Never a background. Never decorative.
     - Amber and red are only ever status. Never a CTA, never a surface.
     - None of the three appears on a marketing page. These tokens are for
       signed-in surfaces only: the shell, the rail, queue rows, job rows.

   Eight status words are written down here even though only five are reachable
   in this build, because publishing does not exist yet. Adding a word later
   costs a migration on work_items; adding it now costs nothing.

     working      blue, which already means the system is doing something
     ready        a GREEN DOT on a neutral chip, never a green fill
     needs review amber
     blocked      red
     approved     neutral gray
     scheduled    neutral gray, unreachable until a scheduler exists
     published    neutral gray, unreachable until publishing exists
     archived     neutral gray

   NOTHING USES THESE YET. Slice A adds them; slice B is the first surface that
   draws against them.
   ========================================================================== */
:root {
  --status-working-fg:     var(--color-blue);
  --status-working-bg:     rgb(35 97 146 / 0.10);

  /* Ready is no longer the exception in this list. Its chip is neutral and its
     dot is green, so the fill token stays neutral on purpose: a green fill
     here would break the containing rule above. Needs review took the same
     three-part shape on 2026-09-09, so a coloured DOT on a neutral chip is
     now the pattern and a coloured foreground is the exception. */
  --status-ready-fg:       var(--color-navy);
  --status-ready-bg:       rgb(158 162 162 / 0.15);
  --status-ready-dot:      var(--color-green);

  /* CORRECTED 2026-09-09, out of the DSK-D04 sitting. Was #B0761A on a 12%
     tint of itself: 3.36:1, under the 4.5 floor, and it had been failing here
     since 2026-08-20. The 2026-08-22 design pass found it and settled #8A5C12
     at 5.08:1, but applied that in site/app.css only, so THIS file kept
     handing out the failing number and the design system kept drawing it.
     That is the same split the type tiers were moved here to end.

     #8A5C12 clears the floor and reads brown, which is the wrong signal for
     caution. The wall is real: a true orange is a light colour, so darkening
     it far enough to carry 13px text walks it to olive every time.

     So needs review takes READY'S SHAPE on the chip: neutral chip, navy words,
     coloured dot. Navy on this tint is 13.9:1, and the dot only has to clear
     the 3:1 floor a mark answers to, which frees the orange to be a real
     orange at 3.4:1 against the tint.

     SPLIT INTO TWO TOKENS 2026-09-17, Brian's call to ship the 2026-09-09
     decision. It was written here and never reached a screen, because
     app.css redefined --status-needs-review-fg as #8A5C12 and loads second,
     so the brown this comment rejects is what rendered for eight days. The
     dot was never drawn at all.

     Deleting that override would have turned six things navy, not one. The
     chip is only one consumer; the other five are TEXT that borrowed the same
     name to mean "the amber ink": a held-back row's reason on Today, Review's
     select-all note, a tab's count badge, the verify-before-posting heading,
     and a Copy button whose text reached the clipboard and not the history.
     Navy there is not a correction, it is the warning going out. One of them,
     .control--outline.is-not-recorded, would have become navy on navy and read
     as an ordinary button.

     So the name each rule already uses keeps its meaning and the chip gets its
     own. --status-needs-review-fg is the amber INK at 5.08:1, which is what
     every text consumer was reading it as. --status-needs-review-chip is the
     chip's word colour. --status-needs-review-dot is finally wired up, in
     site/app.css, beside the ready dot it copies. */
  --status-needs-review-fg:   #8A5C12;
  --status-needs-review-bg:   color-mix(in srgb, #D2600A 10%, var(--color-white));
  --status-needs-review-chip: var(--color-navy);
  --status-needs-review-dot:  #D2600A;

  /* The one place a status signal lands on navy rather than on a white card.
     Moved here from site/app.css 2026-09-17 with the split above, so no status
     token is defined outside this file any more. The settled rule is that
     status chips are light-surface only, and this is not a chip: it is the 6px
     dot on an unselected platform tab, which turns navy when that tab is
     selected. A dark amber on navy is invisible, so the signal needs a light
     variant rather than an exception to the rule. */
  --status-needs-review-on-dark: #F0C98A;

  --status-blocked-fg:     #B03A2E;
  --status-blocked-bg:     rgb(176 58 46 / 0.12);

  /* Approved, scheduled, published and archived are all neutral. They are
     separate tokens rather than one shared name so a later build can separate
     them without a find and replace. */
  --status-approved-fg:    var(--color-paragraph);
  --status-approved-bg:    rgb(158 162 162 / 0.15);
  --status-scheduled-fg:   var(--color-paragraph);
  --status-scheduled-bg:   rgb(158 162 162 / 0.15);
  --status-published-fg:   var(--color-paragraph);
  --status-published-bg:   rgb(158 162 162 / 0.15);
  --status-archived-fg:    var(--color-paragraph);
  --status-archived-bg:    rgb(158 162 162 / 0.15);
}
/* ====================== end product-only status tokens ==================== */

/* ==========================================================================
   PRODUCT-ONLY TYPE TIERS — do not use on a marketing page
   ==========================================================================
   Moved here 2026-09-04 from site/app.css, where they had lived since the
   2026-08-22 design pass that produced them.

   WHY THE MOVE. This file is what the "Avenue Growth Design System" Claude
   Design project syncs. app.css is not, and has no upstream twin. So the one
   real output of that design pass was invisible from the place design
   decisions get made, and the consequence was measurable: of the two screens
   built afterwards, .cal-ahead-note, .cal-filter-label, .cal-tray-hint,
   .compliance-note, .bp-field-label and .open-label all reached past the tiers
   for raw type tokens instead. It also put /brand-profile/ into the phantom
   token bug on 2026-09-01, where .bp-field-note asked for a size that was
   defined in a file that page did not load.

   Counted in launches/AUTHED-PATTERN-INVENTORY.md and held by rule 3 of
   tests/check-tokens.js, which fails on any --tier-* token defined outside
   this file.

   THE CONTAINING RULE, same shape as the status fence above:
     - Three tiers, and small product text picks one of them. A screen that
       needs a fourth is describing a component, not a tier.
     - Never on a marketing page. Marketing type comes from the scale at the
       top of this file, which has section-sized steps rather than these.
     - 10px is the badge carve-out and lives with the badge, not here. A badge
       that needs a sentence in it has stopped being a badge and takes a tier.

     instruction  12px muted. Tells you what to do with the control beside it
     caption      13px muted. Says what a thing is, under or beside it
     proof        13px navy. Carries a measured value the eye should land on

   The .tier-* classes that draw these stay in site/app.css, because a class is
   a component and only signed-in pages have one to draw.
   ========================================================================== */
:root {
  --tier-instruction-size: var(--text-eyebrow);      /* 12px */
  --tier-instruction-ink:  var(--text-body-muted);   /* #696969, 5.49:1 */

  --tier-caption-size:     var(--text-micro);        /* 13px */
  --tier-caption-ink:      var(--text-body-muted);   /* #696969, 5.49:1 */

  --tier-proof-size:       var(--text-micro);        /* 13px */
  --tier-proof-ink:        var(--text-heading);      /* navy, 15.79:1 */
}
/* ======================= end product-only type tiers ====================== */

/* ==========================================================================
   PRODUCT-ONLY SURFACE, DENSITY, STATE & SHAPE TOKENS
   do not use on a marketing page
   ==========================================================================
   Added 2026-09-09 out of the DSK-D04 design sitting. Ten decisions, each
   picked by Brian from rendered comparisons built against this stylesheet on
   reconstructed authed screens, never from swatches or pixel values. The
   spine was editing content, which is the one action that appears on all four
   authed pages, so every option was drawn at four nesting depths.

   Recorded in launches/AUTHED-PATTERN-INVENTORY.md as the answer to the eight
   gaps it measured, plus two found while building the board.

   WHY A THIRD FENCE RATHER THAN NEW ENTRIES ABOVE. Same reason as the status
   palette and the type tiers: a product token loose in the marketing scale
   gets reached for by a marketing page, and 88px sections and 16px rows do
   not belong to one scale. Every token below is signed-in only. Rule 3 of
   tests/check-tokens.js should be extended to fail on any --product-* or
   --surface-product-* token defined outside this file.

   NOTHING USES THESE YET. DSK-D05 is the rewrite that draws against them.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Surface and elevation                                        (chose 1c)
   --------------------------------------------------------------------------
   Product stacks a drawer on a panel on a page and the brand forbids shadows,
   so depth is carried by fill AND border together. Two cues fail differently,
   and a stack four deep is where one cue runs out.

   THE CONTAINING RULE:
     - A BORDER MEANS RAISED. A recessed surface loses its border entirely and
       is read by fill alone. This is the whole rule; it is what stops a well
       and a card from looking like siblings.
     - Four levels, and nothing invents a fifth. Page, panel, well, drawer.
     - The scrim is the only transparency in the system besides the dialog
       scrim it matches. No blur, ever.
   -------------------------------------------------------------------------- */
:root {
  --surface-product-page:   color-mix(in srgb, var(--color-navy) 5%, var(--color-white));
  --surface-product-panel:  var(--color-white);
  --surface-product-well:   color-mix(in srgb, var(--color-navy) 7%, var(--color-white));

  /* A panel is raised off the page, so it has a border. A drawer is raised off
     the panel, so its border is the stronger one. A well is recessed, so it
     has no border at all and the fill above does the work. */
  --border-product-panel:  1px solid var(--border-default);
  --border-product-drawer: 1px solid var(--border-strong);
  --border-product-well:   none;

  --scrim-product: rgb(12 35 64 / 0.55);
}

/* --------------------------------------------------------------------------
   2. Product density                                              (chose 2a)
   --------------------------------------------------------------------------
   One rhythm for the whole product, at half the marketing step. Chosen over a
   two-density scale because editing content happens on Today, Review, Calendar
   AND Create One Post, so there is no clean split between a surface you scan
   and a surface you edit. A density switch would make every new screen decide
   which it is, and the inventory already shows what screens do when the system
   makes them decide something: four private prefixes.

   THE CONTAINING RULE:
     - 4px is the ONLY sub-8 value and it is legal INSIDE A CONTROL only:
       between a dot and its label, an icon and its text. Never between two
       components. This is the carve-out that keeps the 8px grid true, and it
       is an escape hatch the moment it appears in a gap between siblings.
     - Section padding tokens at the top of this file are for marketing. A
       product panel takes --space-product-panel, not --space-lg.
     - 44px is the mobile hit-target floor and it is not negotiable by density.

   CORRECTION FROM THE BOARD: the rendered 2a frame used 20px panel padding and
   34px control heights. Both are off the 8px grid, both were mine, and neither
   is tokenised here. The values below round them onto the grid.
   -------------------------------------------------------------------------- */
:root {
  --space-product-2xs: 4px;   /* inside a control only. See the rule above. */
  --space-product-xs:  8px;   /* gap between sibling controls */
  --space-product-sm:  16px;  /* row padding, and the inside of a well */
  --space-product-md:  24px;  /* panel padding, and between stacked panels */
  --space-product-lg:  32px;  /* between the sections of one screen */

  --control-product-height:        40px;
  --control-product-height-mobile: 44px;

  --row-product-pad:   var(--space-product-sm);
  --panel-product-pad: var(--space-product-md);
}

/* --------------------------------------------------------------------------
   3. Interactive states                                           (chose 3b)
   --------------------------------------------------------------------------
   The marketing states are a button's states. Dimming to 90% works on a green
   fill and does nothing to a white row on a white page, and pressing a 900px
   row down by 2% wobbles it.

   So a filled control keeps the dim and the press, because it has a fill to
   dim. Anything wide enough to hold a row of content hovers by picking up a
   navy tint and presses by deepening it.

   THE CONTAINING RULE:
     - NOTHING WIDER THAN A CONTROL EVER SCALES. No transform on a row, a
       panel, a drawer, a calendar day or a queue item. That is what stops a
       long list from feeling loose.
     - A surface answers the cursor with fill, never with a border change: the
       border is carrying elevation and cannot also carry hover.
     - Buttons keep --state-hover-opacity and --state-press-scale from the top
       of this file. These tokens do not replace them, they cover what those
       two cannot reach.
   -------------------------------------------------------------------------- */
:root {
  --state-product-surface-hover: color-mix(in srgb, var(--color-navy) 4%, var(--color-white));
  --state-product-surface-press: color-mix(in srgb, var(--color-navy) 8%, var(--color-white));
}

/* --------------------------------------------------------------------------
   4. The extra colours, each with the job it may do    (chose 4b, then 4c)
   --------------------------------------------------------------------------
   Four jobs, and one new colour. Every token here is bound to a job with the
   rule written beside it. A colour no component composes with is invisible,
   which is why the earlier extra colours did not stick.

     selection      a navy fill, on a control the user has picked
     destructive    a deep red, on an action that cannot be taken back
     drop target    blue, on the day a dragged post will land

   SELECTION WENT TO 4c ON 2026-09-09, and this block called the shot itself.
   It was written as 4b, blue at 10%, with the escape hatch beside it: "if that
   pair ever reads as one thing on a real screen, selection moves to navy (the
   4c option) rather than blue getting a second meaning."

   It already had. On the day this was written, content-strategist had been
   drawing a NAVY FILL for topic, platform, tone, format and the drawer's
   switches since 2026-08, under a comment titled "one selection language". So
   the blue tint was the answer to a question five live sets of controls had
   already answered the other way, and DSK-D05's extraction is what surfaced
   that: it could not build one .choice component while two rules disagreed.
   Brian settled it on 2026-09-09 and navy won.

   The 4b values are gone rather than left sitting here unused. Two undrawn
   colours in a token file is the exact failure the paragraph above describes,
   and keeping them would have made the escape hatch look like it was still
   open when it has been taken.

   THE CONTAINING RULE, per job:
     - SELECTION is a navy fill with white on it, on a filter chip, a platform
       toggle, a tone, a format or a calendar day. It may NOT be a status, and
       it may not appear as a pill: a pill means status or tier and never
       anything pressable. SHAPE IS STILL WHAT DOES THE WORK, and it does more
       of it now, since navy is also the shell's own colour. A selected thing
       is a filled control with a 6px corner; a status is a 999px pill that
       cannot be pressed; the rail is a full-height surface. If any two of
       those ever read as one thing, the answer is shape again, never a fourth
       colour.
     - DESTRUCTIVE is a 1.5px border and a label, never a fill, and never more
       than one per dialog. It may NOT be used for blocked, which is a status
       the system set rather than an action you can take. It is a deeper red
       than --status-blocked-fg on purpose, so the two do not read as equals.
       IT IS UNDRAWN, and unlike selection that is correct: nothing in the
       product deletes anything irreversibly yet, so it has no consumer. The
       first screen that does takes these two.
     - DROP TARGET only ever appears mid-drag, and it is a dashed border plus
       a pale fill so it cannot be mistaken for a selected day.
     - None of these is a CTA. The CTA is green and stays green.
   -------------------------------------------------------------------------- */
:root {
  /* Drawn by .choice.is-selected in site/app.css, on both fill and border.
     White on this navy measures 15.79:1. */
  --select-product-bg: var(--color-navy);
  --select-product-fg: var(--color-white);

  --action-destructive-fg: #8C2F22;         /* 8.3:1 on white */
  --action-destructive-border: 1.5px solid var(--action-destructive-fg);

  --drop-target-line: var(--color-blue);
  --drop-target-bg:   rgb(35 97 146 / 0.06);
}

/* --------------------------------------------------------------------------
   5. The display face behind the login                            (chose 5b)
   --------------------------------------------------------------------------
   Inter alone. Jost is a Google Fonts STAND-IN for Sackers Gothic, which has
   no web licence. Spending a substitute sparingly on marketing is a
   compromise; spending it on the surface someone works in every day spreads
   that compromise to where it costs the most.

   Inter is also drawn for screen UI at 13 to 15px, which is where product
   type lives, and the type tiers already settled that product hierarchy comes
   from ink and scale rather than a second face.

   CORRECTION FROM THE BOARD: I first argued this on width, that Jost is wider
   and would break the drawer tab strip. I measured it afterwards and it is
   false. "Voice & CTA" sets at 77px in Jost against 82px in Inter, and both
   strips fit the contract's 392px drawer with 50 to 70px spare. Width decides
   nothing here. The argument is licence and legibility, and it stands without
   the width claim.

   THE CONTAINING RULE:
     - Marketing keeps Jost via --font-display. Graphic cards keep real
       Sackers. The login is the boundary.
     - This is a SEAM, not a duplicate: it points at the body face today, so
       the day real Sackers webfonts arrive it is one line here rather than a
       hunt through app.css.
     - No product surface references --font-display directly. That is what
       makes the seam worth having.
   -------------------------------------------------------------------------- */
:root {
  --font-product-display: var(--font-body);
}

/* --------------------------------------------------------------------------
   9. The nested radius                                            (chose 9a)
   --------------------------------------------------------------------------
   The system had three radii and none of them was for a small object sitting
   inside a card, so pages were inventing one: the board itself had a 3px post
   block and a 4px day cell that no token authorised.

   A child inside a 10px card with 16px padding wants a smaller radius than its
   parent, or its corners fight the parent's.

   THE CONTAINING RULE:
     - Objects INSIDE a card only: a post block on a calendar day, a thumbnail,
       a colour swatch, a small numeric marker.
     - NEVER on a control. A button, input or select takes 6px whatever it sits
       inside, so that pressable things keep one corner across the product.
     - A pill stays a pill. 999px means status or tier, and the jump from 6px
       to 999px is intended rather than drift: it is how you can tell at a
       glance that a thing is not pressable.
   -------------------------------------------------------------------------- */
:root {
  --radius-product-nested: 4px;
}

/* --------------------------------------------------------------------------
   Decisions from this sitting that produce no token
   --------------------------------------------------------------------------
   Recorded here because a decision the design system cannot see is a decision
   the next screen half-adopts, which is the lesson of the amber above. These
   three are copy and layout, so DSK-D05 implements them in site/app.css and
   the authed templates.

   6. THE CALENDAR'S HIDDEN WRITE                                 (chose 6f)
   The status picker stays a list of four peer states: Ready, Approved,
   Scheduled, Posted. None of them is qualified, because Scheduled is its own
   status word and "Approved, not scheduled" makes Approved read as a lesser
   Scheduled. The write is said out loud in the line under the picker, and the
   button repeats it in the same words:

     line:   "Approved has no day. Choosing that status clears any selected
              date and places the post under Not scheduled."
     button: "Clear selected day"

   The tray is renamed "Not scheduled" on every screen it appears on. Approved
   stays in the picker, because it is the only way back from a mis-tapped
   Posted.

   7. THE WEEK VIEW ON A PHONE                                    (chose 7b)
   Seven rows down the screen, not seven columns. A week is seven items and a
   phone lists seven items well, so a readable topic beats a recognisable
   shape. The month view keeps its grid. The two views no longer match, and
   that is accepted rather than worked around.
   Each row carries its status as a DOT, matching the chip pattern above. A
   coloured left border was drawn on the first board and removed: the brand
   guide bans a coloured left border on a card, and it was a second mechanism
   for something the dot already says.

   8. A QUESTION ASKED MID-FLOW                                   (chose 8e)
   The ask replaces the Generate button rather than unfolding inside the
   essentials, so the essentials stay at two to four decisions whatever the
   question count is. The ask is a STEP, not a section.
     - It names the count up front ("Three things before this one", "1 of 3"),
       so the interruption is bounded and its end is visible.
     - Every ask states the save in the ask itself, per CONTRACT-DISCLOSURE:
       asked once, saves to the Brand Profile, changeable there.
     - "Use it once, do not save" ships with it. It is not a nicety: it is the
       only thing that makes the ask an ask rather than a toll.
     - Answers land in a "Your stories" panel on the Brand Profile, each row
       editable, so asking once is a promise the profile can keep.
   -------------------------------------------------------------------------- */

/* ============= end product-only surface, density & shape tokens =========== */
