/* ==========================================================================
   Theme: CONTRAST
   Loaded AFTER site.css, every rule scoped to [data-theme="contrast"].
   Additive by design — site.css is untouched, so the classic build stays
   byte-identical (verified by freeze_check.py against content/classic.sha256).

   Five moves, all mechanism rather than redesign:
     1. alternating grounds — smoky black against sand
     2. alternating asymmetry — the rail changes sides with the ground
     3. scroll-reactive header, grounded with a blur off the top
     4. full-height dropdown panels
     5. reveal footer — the page scrolls up off a pinned footer
   Plus the emblem splash on the landing page.

   COLOUR LAW IS UNCHANGED. Components still paint var(--accent); only the
   token VALUES change inside a sand section, so a neutral page still cannot
   render an ecosystem colour. Every value below is measured, not picked.
   ========================================================================== */

[data-theme="contrast"]{
  /* Motion runs longer than classic's 200-300ms. Deliberate: the reference
     for this look moves at 500-1000ms, and a pinned footer or a full-height
     panel at 250ms reads as a jump-cut rather than a move. Still no bounce,
     still transition-only. audit.py holds site.css to the original band and
     this file to the wider one. */
  --dur-panel:420ms;
  --dur-lift:520ms;
  --dur-splash:700ms;

  /* Light-ground variants.
     White is the contrast; sand is an accent and a band, not a ground. The
     existing --*-on-light tokens were measured against #FFFFFF and are used
     as-is here — that is exactly the ground they were derived for. */
  --lt-ground:#FFFFFF;
  --lt-card:#F7F4EE;        /* 1.10:1 lift — same subtlety as card-on-page in dark */
  --lt-well:#F0EBE1;
  --lt-rule:#E0D8C9;
  --lt-body:#454039;        /* 10.27:1 on white · 9.35:1 on card */
  --lt-muted:#625A50;       /*  6.78:1 on white · 6.18:1 on card */
  --lt-head:#1A1713;        /* 17.86:1 on white */
  --lt-sand-fill:#C0A87A;   /* sand as a visible rule/fill on white */
  --lt-sand-text:#7A663F;   /*  5.53:1 on white · 5.03:1 on card */

  /* Sand BAND variants — for the short banner sections that still take sand.
     violet-on-light lands at 4.44:1 on sand and mint-on-light at 3.48:1, both
     under AA, which is why these exist separately from the --*-on-light set. */
  --sand-ground:#DECFB2;
  --sand-card:#EDE3D0;
  --sand-rule:#BCA983;
  --sand-body:#4A4034;      /* 6.59:1 on sand */
  --sand-muted:#584D3E;     /* 5.37:1 on sand */
  --sand-head:#241F19;      /* 10.64:1 on sand */
  --mint-text-on-sand:#0F5C3B;    /* 5.23:1 on sand */
  --violet-text-on-sand:#4A2FB8;  /* 5.72:1 on sand */
}

/* ==========================================================================
   1 · GROUNDS — white against smoky, sand as a band
   Every second top-level section takes WHITE. The hero is always first, so it
   always stays smoky. Sand is reserved for the short banner sections, where it
   reads as a band rather than as a page ground.
   Redefining the TOKENS (not the colours) is what keeps the colour law intact:
   .tile still says background:var(--card), it just resolves differently here.
   ========================================================================== */
[data-theme="contrast"] main > section:nth-of-type(even){
  --page:var(--lt-ground);
  --card:var(--lt-card);
  --well:var(--lt-well);
  --rule:var(--lt-rule);
  --body:var(--lt-body);
  --muted:var(--lt-muted);
  --white:var(--lt-head);
  --violet-text-on-dark:var(--violet-text-on-light);
  --mint-text-on-dark:var(--mint-text-on-light);
  /* --sand is the accent here, never the ground. Anything still painting raw
     --sand (stage numerals, rails, the source marker) resolves to the ink
     counterpart so it stays legible. */
  --sand:var(--lt-sand-text);
  background:var(--lt-ground);
  color:var(--lt-body);
}
[data-theme="contrast"][data-eco="beneco"] main > section:nth-of-type(even){
  --accent:var(--violet-text-on-light);
  --accent-text:var(--violet-text-on-light);
  --accent-ink:var(--lt-ground);
}
[data-theme="contrast"][data-eco="reveco"] main > section:nth-of-type(even){
  --accent:var(--mint-text-on-light);
  --accent-text:var(--mint-text-on-light);
  --accent-ink:var(--lt-ground);
}
[data-theme="contrast"][data-eco="none"] main > section:nth-of-type(even){
  --accent:var(--lt-sand-fill);
  --accent-text:var(--lt-sand-text);
  --accent-ink:var(--lt-head);
}

/* ---- sand, as a band ------------------------------------------------------
   The trust bar and the closing CTA are short and banner-shaped, so they carry
   the sand rather than a whole reading section. This is the move that keeps
   sand as an accent colour instead of a second page ground. */
[data-theme="contrast"] main > section.trustbar,
[data-theme="contrast"] main > section.ctablock{
  --page:var(--sand-ground);
  --card:var(--sand-card);
  --well:var(--sand-card);
  --rule:var(--sand-rule);
  --body:var(--sand-body);
  --muted:var(--sand-muted);
  --white:var(--sand-head);
  --violet-text-on-dark:var(--violet-text-on-sand);
  --mint-text-on-dark:var(--mint-text-on-sand);
  --sand:var(--sand-body);
  background:var(--sand-ground);
  color:var(--sand-body);
  border-top:0;
}
[data-theme="contrast"][data-eco="none"] main > section.trustbar,
[data-theme="contrast"][data-eco="none"] main > section.ctablock{
  --accent:var(--sand-body);
  --accent-text:var(--sand-body);
  --accent-ink:var(--sand-ground);
}

/* A ground change is its own divider — a hairline on top of it reads as an
   accident rather than as structure. */
[data-theme="contrast"] main > section:nth-of-type(even).rule-top,
[data-theme="contrast"] main > section:nth-of-type(even) + section.rule-top{
  border-top:0;
}

/* The emblem watermark is sand by law. On a light ground it needs to invert to
   read at all; still decorative, still under the audited opacity ceiling. */
[data-theme="contrast"] main > section:nth-of-type(even).wm::after{
  filter:invert(1) sepia(1) saturate(.45) hue-rotate(350deg);
  opacity:.05;
}

/* ---- "Where it starts" stays smoky on every ground ------------------------
   It is the one block on the site that states the commercial terms, and it
   holds better as an inset dark panel than as another light card. Tokens are
   re-asserted inside it so its children resolve against the dark ground. */
[data-theme="contrast"] .twostep,
[data-theme="contrast"] .stages{
  --page:#282828;
  --card:#2E2E2E;
  --well:#252525;
  --rule:#3C3C3C;
  --body:#B4B4B8;
  --muted:#9A9AA2;
  --white:#FFFFFF;
  --sand:#DECFB2;
  --violet-text-on-dark:#9B85FF;
  --mint-text-on-dark:#5FD19A;
  background:#282828;
  color:#B4B4B8;
  border:1px solid #3C3C3C;
  border-left:3px solid var(--sand);
  border-radius:4px;
  padding:clamp(1.5rem,3vw,2.25rem);
}
[data-theme="contrast"] .twostep .h3,
[data-theme="contrast"] .stages .h3{color:#FFFFFF}

/* ==========================================================================
   2 · ALTERNATING ASYMMETRY
   The rail keeps its width but changes sides with the ground, and the wide
   split flips its weighting. Same grid, different rhythm — this is the SDI
   move, and it is what stops a long page reading as a template.
   ========================================================================== */
@media(min-width:980px){
  [data-theme="contrast"] main > section:nth-of-type(even) > .split{
    grid-template-columns:minmax(0,1fr) 13rem;
  }
  [data-theme="contrast"] main > section:nth-of-type(even) > .split > :first-child{
    order:2;
    text-align:right;
  }
  [data-theme="contrast"] main > section:nth-of-type(even) > .split > :nth-child(2){
    order:1;
  }
  [data-theme="contrast"] main > section:nth-of-type(even) > .split-wide{
    grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  }
  /* Every fourth section runs a wider rail, so the rhythm is a cycle rather
     than a two-beat flip. */
  [data-theme="contrast"] main > section:nth-of-type(4n+3) > .split{
    grid-template-columns:17rem minmax(0,1fr);
  }
}

/* ==========================================================================
   3 · SCROLL-REACTIVE HEADER
   Retracts on the way down, returns on the way up, and grounds itself with a
   blur once it is off the top of the page. On long lever pages this is a
   reading improvement, not decoration.
   ========================================================================== */
[data-theme="contrast"] .header{
  transition:transform var(--dur-panel) var(--ease),
             background-color var(--dur-panel) var(--ease),
             border-color var(--dur-panel) var(--ease);
}
[data-theme="contrast"] .header.is-retracted{transform:translateY(-100%)}
[data-theme="contrast"] .header.is-grounded{
  background:color-mix(in srgb,var(--page) 78%,transparent);
  -webkit-backdrop-filter:blur(14px) saturate(1.3);
  backdrop-filter:blur(14px) saturate(1.3);
  border-bottom-color:var(--rule);
}
@supports not (backdrop-filter:blur(2px)){
  [data-theme="contrast"] .header.is-grounded{background:var(--page)}
}
@media (prefers-reduced-motion:reduce){
  [data-theme="contrast"] .header{transition:none}
  [data-theme="contrast"] .header.is-retracted{transform:none}
}

/* ==========================================================================
   5 · REVEAL FOOTER
   The stack scrolls up off a pinned footer. Pure CSS; the only script is the
   one that measures the footer and reserves that much room beneath the stack.
   Off below 900px and whenever the footer is too tall to be revealed.
   ========================================================================== */
[data-theme="contrast"] .page-stack{
  position:relative; z-index:1; background:var(--page);
}
html.footer-pinned[data-theme="contrast"] .footer{
  position:fixed; left:0; right:0; bottom:0; z-index:0;
}
html.footer-pinned[data-theme="contrast"] .page-stack{
  box-shadow:0 24px 60px rgba(0,0,0,.45);
}

/* ==========================================================================
   6 · SPLASH
   Hunter's is an MP4. This is the real emblem, wiped in with a clip-path
   transition and lifted off — staged from script so the motion stays
   transition-only and the existing no-@keyframes law still holds.
   ========================================================================== */
html.splash-lock,html.splash-lock body{overflow:hidden}
[data-theme="contrast"] .splash{
  position:fixed; inset:0; z-index:999;
  display:grid; place-items:center;
  background:var(--page);
  transform:translateY(0);
  transition:transform var(--dur-lift) var(--ease),
             opacity var(--dur-lift) var(--ease);
}
[data-theme="contrast"] .splash.is-lifting{
  transform:translateY(-100%); opacity:0;
}
[data-theme="contrast"] .splash-inner{
  display:grid; place-items:center; gap:1.75rem;
}
[data-theme="contrast"] .splash-mark{
  width:min(46vh,21rem); height:auto;
  opacity:0;
  transform:scale(.94);
  clip-path:inset(0 100% 0 0);
  transition:clip-path var(--dur-splash) var(--ease),
             opacity var(--dur-panel) var(--ease),
             transform var(--dur-splash) var(--ease);
}
[data-theme="contrast"] .splash.is-in .splash-mark{
  opacity:1; transform:scale(1); clip-path:inset(0 0 0 0);
}
[data-theme="contrast"] .splash-word{
  font-size:var(--fs-micro); letter-spacing:var(--ls-caps);
  text-transform:uppercase; font-weight:700; color:var(--sand);
  opacity:0; transform:translateY(6px);
  transition:opacity var(--dur-lift) var(--ease) 260ms,
             transform var(--dur-lift) var(--ease) 260ms;
}
[data-theme="contrast"] .splash.is-in .splash-word{opacity:1; transform:none}
@media (prefers-reduced-motion:reduce){
  [data-theme="contrast"] .splash{display:none}
}

/* --------------------------------------------------------------------------
   Footer, compacted for the pin.
   A pinned footer only works if it is shorter than the viewport — otherwise
   there is nothing scrolling can reveal. The classic footer runs 816px at
   880px tall, which fails that test on every laptop. Tightening the rhythm
   here (not in site.css) brings it under without losing a single link.
   -------------------------------------------------------------------------- */
[data-theme="contrast"] .footer{padding-block:3.25rem 2.25rem}
[data-theme="contrast"] .footer h4{margin-bottom:.55rem}
[data-theme="contrast"] .footer li{margin-bottom:.2rem;line-height:1.45}
[data-theme="contrast"] .footer .legal{margin-top:1.5rem;padding-top:1rem}
@media(min-width:900px){
  /* Five tracks, matching site.css — four left Resources on a row of its own.
     One row instead of two also shortens the footer, which is what the pinned
     reveal needs. */
  [data-theme="contrast"] .footer-grid{
    grid-template-columns:minmax(0,1.15fr) repeat(4,minmax(0,1fr));
    gap:1.25rem 1.75rem;
  }
}

/* --------------------------------------------------------------------------
   Footer, compacted further so the pin actually engages.
   A pinned footer only works if it is shorter than the viewport. At 665px it
   cleared an 880px preview and failed a real 780px browser window — which is
   why the reveal looked broken outside the preview pane.
   -------------------------------------------------------------------------- */
[data-theme="contrast"] .footer{padding-block:2.5rem 1.75rem}
[data-theme="contrast"] .footer li{font-size:var(--fs-micro);line-height:1.5}
[data-theme="contrast"] .footer .legal{margin-top:1.1rem;padding-top:.85rem;
  font-size:var(--fs-micro)}

/* Same logic for the stage rows: name, price and description on one line
   instead of three stacked ones. */
@media(min-width:720px){
  [data-theme="contrast"] .ts-list li{
    grid-template-columns:auto minmax(0,1fr) auto;
    align-items:baseline;
    gap:.3rem 1.25rem;
    padding-block:.7rem;
  }
  [data-theme="contrast"] .ts-list li::before{
    grid-column:1;grid-row:1;align-self:baseline;
  }
  [data-theme="contrast"] .ts-name{grid-column:2;grid-row:1}
  [data-theme="contrast"] .ts-price{grid-column:3;grid-row:1;justify-self:end}
  [data-theme="contrast"] .ts-desc{grid-column:2/4;grid-row:2}
}

/* --------------------------------------------------------------------------
   The Foundation mirrors the stage rows: name and tag on one line, the claim
   and the descriptor under them. It inherits the smoky inset from .twostep.
   -------------------------------------------------------------------------- */
@media(min-width:720px){
  [data-theme="contrast"] .found-row{
    grid-template-columns:minmax(0,1fr) auto;
    gap:.4rem 1.25rem;
  }
  [data-theme="contrast"] .found-tag{justify-self:end}
}

/* --------------------------------------------------------------------------
   Ecosystem tint on the ECO pages' cards.
   The card paints var(--accent) — it never names mint or violet — so BenECO
   comes out purple and RevECO green from the same rule, and a neutral page
   still cannot render either. --accent is already resolved per ground, so the
   tint works on the white sections and the smoky ones without a second value.
   -------------------------------------------------------------------------- */
[data-theme="contrast"][data-eco="beneco"] .tile,
[data-theme="contrast"][data-eco="reveco"] .tile{
  background:color-mix(in srgb, var(--accent) 8%, var(--card));
  border-color:color-mix(in srgb, var(--accent) 32%, var(--rule));
}

/* Tinting the card moves the ground its accent text sits on, and two of the
   four combinations had no headroom: violet-on-dark was 4.65:1 against a plain
   card and fell to 4.29 once tinted; mint-on-light went 5.35 -> 4.39. Both are
   corrected here rather than by watering the tint down to 3%, which is the only
   level the original values survive and is invisible.
   --accent-text has to be set directly, not via its source token: var() is
   substituted where the property is DECLARED, so redefining
   --violet-text-on-dark on the tile leaves the --accent-text it inherited from
   the section untouched. Small text is the binding case — the 24px card
   headings were never at risk.
     violet on a tinted dark card   #9B85FF -> #A793FF   4.93:1
     mint   on a tinted light card  #157A4E -> #127045   5.02:1            */
/* (the corrected values above are no longer needed — the fill was dropped) */
[data-theme="contrast"][data-eco="beneco"] .tile .h3,
[data-theme="contrast"][data-eco="reveco"] .tile .h3{color:var(--accent-text)}
[data-theme="contrast"][data-eco="beneco"] .tile:hover,
[data-theme="contrast"][data-eco="reveco"] .tile:hover{
  background:color-mix(in srgb, var(--accent) 14%, var(--card));
  border-color:var(--accent);
}

/* --------------------------------------------------------------------------
   The Snapshot CTA takes the page's colour too.
   Ecosystem pages get their own accent; neutral pages get sand, because a
   neutral page must not be able to render either ecosystem colour. Both
   fills are existing brand tokens with their existing ink pairing —
   --btn-secondary-bg is the mint button, already specified in §9.2, and it
   belongs to RevECO since the colour flip (30 Oct 2026).
   --sand-ground is used rather than --sand, which the light sections
   redefine to its ink counterpart.
   -------------------------------------------------------------------------- */
[data-theme="contrast"][data-eco="reveco"] .btn-primary{
  background:var(--btn-secondary-bg);
  color:var(--btn-secondary-text);
}
[data-theme="contrast"][data-eco="none"] .btn-primary{
  background:var(--sand-ground);
  color:var(--lt-head);
}

/* --------------------------------------------------------------------------
   Cards keep their own ground; the colour lives in the edge and the heading.
   This drops the tinted fill, which also removes the reason the accent-text
   values had to be corrected — an untinted card puts them back on the ground
   they were measured against.
   -------------------------------------------------------------------------- */
[data-theme="contrast"][data-eco="beneco"] .tile,
[data-theme="contrast"][data-eco="reveco"] .tile{
  background:var(--card);
  border-color:color-mix(in srgb, var(--accent) 55%, var(--rule));
}
[data-theme="contrast"][data-eco="beneco"] .tile:hover,
[data-theme="contrast"][data-eco="reveco"] .tile:hover{
  background:var(--card);
  border-color:var(--accent);
}

/* The foundation band's name stays sand — it belongs to both, and is the one
   lever the section exists to name. */
[data-theme="contrast"] .found-name{color:var(--accent-text)}

/* --------------------------------------------------------------------------
   The CTA inside a sand band inverts.
   Sand-on-sand is not a button. Ink fill, sand text — the same pair the band
   already uses for its own type, reversed.
   -------------------------------------------------------------------------- */
[data-theme="contrast"] main > section.ctablock .btn-primary,
[data-theme="contrast"] main > section.trustbar .btn-primary,
[data-theme="contrast"] main > section.foundation .btn-primary{
  background:var(--sand-head);
  color:var(--sand-ground);
}

[data-theme="contrast"] .splash-motto{
  display:block; margin-top:1.1rem;
  font-size:var(--fs-4); font-weight:700; color:var(--white);
  opacity:0; transform:translateY(6px);
  transition:opacity var(--dur-lift) var(--ease) 420ms,
             transform var(--dur-lift) var(--ease) 420ms;
}
[data-theme="contrast"] .splash.is-in .splash-motto{opacity:1; transform:none}

/* --------------------------------------------------------------------------
   Motto hero — static. The typewriter was removed (Ben, 29 Oct 2026) as a
   distraction on arrival; any new animation is a fresh design.
   -------------------------------------------------------------------------- */
/* Stacked, one clause per line, in the right-hand rail. */
/* The motto is the display headline; .display already carries its size,
   weight and tracking. Only the stacking is specific to it. */
[data-theme="contrast"] .motto{margin:0}
[data-theme="contrast"] .motto .m-line{
  display:block;
  position:relative;
  /* Each clause holds one line where there is room. Below that it has to be
     allowed to wrap — "One partner for both." at display size is wider than a
     375px screen, and nowrap pushed the page into horizontal scroll. */
  white-space:normal;
}
@media(min-width:600px){
  [data-theme="contrast"] .motto .m-line{white-space:nowrap}
}





/* --------------------------------------------------------------------------
   Hero: the emblem sits beside the HEADLINE, not the paragraph.
   Two rows — headline and mark share row 1, the paragraph and buttons take
   row 2 under the headline. The mark is centred on the headline's row, so it
   reads as a counterweight to the type rather than an ornament beside the
   body copy. Its column is the width of the header's Snapshot button and
   shares that button's right edge, so it hangs directly beneath it.
   -------------------------------------------------------------------------- */
[data-theme="contrast"] .hero-mark{display:none}
[data-theme="contrast"] .hero-rail > .lede,
[data-theme="contrast"] .hero-body > .lede{margin-top:var(--sp-head)}
@media(min-width:960px){
  [data-theme="contrast"] .hero-rail{
    display:grid;
    grid-template-columns:minmax(0,1fr) 315px;
    column-gap:clamp(2rem,4.5vw,4.5rem);
  }
  [data-theme="contrast"] .hero-rail > h1{grid-column:1;grid-row:1}
  [data-theme="contrast"] .hero-body{grid-column:1;grid-row:2}
  [data-theme="contrast"] .hero-mark{
    display:block; grid-column:2; grid-row:1;
    align-self:center; justify-self:start;
  }
  [data-theme="contrast"] .hero-mark img{
    display:block; width:min(100%,14rem); height:auto;
  }
}
