/* Landing page sections: hero, steps, styles, pricing, FAQ. */

/* Hero: dark ground with the render wall behind the pitch and the
   sign-in card (owner ask 2026-09-03, after interiorai's lander; the
   light hero read as white space). The wall is a tilted grid of our
   own proof tiles drifting slowly; a scrim keeps the copy legible and
   the ground fades to solid ink before the steps strip. Copy and
   controls that sit on this ground take paper, never gray. */

.hero {
  position: relative;
  overflow: clip;
  /* Safari painted the whole window black for the first seconds of a
     load while the wall's big 3D layers came up (owner report
     2026-09-03, reproduced in Safari): paint containment keeps every
     descendant inside the hero's box from the first frame. */
  contain: paint;
  background: var(--ink);
  color: var(--paper);
  padding-block: var(--space-8) var(--space-7);
}

.hero > .container {
  position: relative;
  z-index: 1;
}

.hero-wall {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

/* The wall: one set of ten tiles is 2520px wide (10 x 240px plus ten
   12px gaps, the marquee loop math), so the grid is exactly one set
   wide and every row's window is always covered while its track loops
   at -50%. Scaled past the viewport and tilted; each row scrolls on
   its own duration, staggered by negative delays so no column ever
   lines up. */
.hero-wall-grid {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 2520px;
  opacity: 0.74;
  transform: translate(-50%, -50%) perspective(1400px) rotateX(22deg) rotateZ(-8deg) scale(1.12);
  /* The tiles decode a beat after first paint and used to land as one
     block (Safari capture 2026-09-03); a fade over the first second
     turns that into an arrival, timed after the headline rises. */
  animation: hero-wall-in 1400ms ease-out 250ms both;
}

@keyframes hero-wall-in {
  from { opacity: 0; }
  to { opacity: 0.74; }
}

.hero-wall .marquee {
  --marquee-gap: var(--space-3);
  overflow: hidden;
}

/* The gallery marquee pins its tracks to their own layers for the
   hover-pause; the wall has no hover, and five pinned 5040px layers
   inside a 3D transform are what WebKit was allocating black. */
.hero-wall .marquee-track {
  will-change: auto;
}

.hero-wall-row + .hero-wall-row {
  margin-top: var(--space-3);
}

.hero-wall-row:nth-child(2) .marquee-track { animation-delay: -19s; }
.hero-wall-row:nth-child(3) .marquee-track { animation-delay: -41s; }
.hero-wall-row:nth-child(4) .marquee-track { animation-delay: -9s; }
.hero-wall-row:nth-child(5) .marquee-track { animation-delay: -53s; }
.hero-wall-row:nth-child(6) .marquee-track { animation-delay: -27s; }
.hero-wall-row:nth-child(7) .marquee-track { animation-delay: -47s; }
.hero-wall-row:nth-child(8) .marquee-track { animation-delay: -15s; }

.hero-wall-grid img {
  display: block;
  width: 15rem;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-sm);
}

/* Below the two-column layout the hero stacks and grows tall (about
   1,500px at tablet widths, 1,200px on phones) while the wall is a
   fixed six rows, so it scales up to keep covering; width is abundant
   there. */
/* Biased upward: the hero's foot is solid ink under the scrim, its
   head is not, and the 8-degree tilt lowers the wall's top edge at
   the left. */
@media (max-width: 959px) {
  .hero-wall-grid {
    transform: translate(-50%, -56%) perspective(1400px) rotateX(22deg) rotateZ(-8deg) scale(1.6);
  }
}

@media (max-width: 719px) {
  .hero-wall-grid {
    transform: translate(-50%, -55%) perspective(1400px) rotateX(22deg) rotateZ(-8deg) scale(1.4);
  }
}

/* The scrim: heavier under the pitch on the left, solid at the foot so
   the section closes on ink rather than on a tile edge. */
.hero-wall::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 70% at 28% 45%, rgba(16, 16, 16, 0.6), transparent 72%),
    linear-gradient(180deg, rgba(16, 16, 16, 0.62) 0, rgba(16, 16, 16, 0.34) 7rem, rgba(16, 16, 16, 0.44) 60%, var(--ink) 100%);
}

/* The stillness toggle (WCAG 2.2.2), the gallery marquee's own, in the
   hero's corner on the dark ground. marquee.css hides it under
   reduced motion, where the rows never move. */
/* Specificity on purpose: marquee.css loads after this file and its
   own .marquee-toggle rules (ink text, ink hover) would otherwise paint
   the button ink on ink (owner report 2026-09-03). */
.hero .hero-wall-toggle {
  position: absolute;
  right: var(--space-4);
  bottom: var(--space-3);
  z-index: 2;
  color: rgba(251, 251, 248, 0.75);
  border-color: rgba(251, 251, 248, 0.4);
}

.hero .hero-wall-toggle:hover,
.hero .hero-wall-toggle:focus-visible {
  color: var(--paper);
  border-color: var(--paper);
  outline-color: var(--accent-soft);
}

/* The kicker over the wall: paper with a hairline ink shadow, the
   accent kept as a leading rule (owner: the soft blue on the tiles was
   hard to read, 2026-09-03). */
.hero .kicker {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  color: rgba(251, 251, 248, 0.88);
  text-shadow: 0 1px 2px rgba(16, 16, 16, 0.7);
}

.hero .kicker::before {
  content: "";
  width: 1.5em;
  height: 2px;
  background: var(--accent-soft);
}

.hero-inner {
  display: grid;
  gap: var(--space-6);
  max-width: 54rem;
}

.hero h1 {
  font-size: var(--text-h1);
  color: var(--paper);
}

.hero h1 em {
  font-style: normal;
  color: var(--accent-soft);
}

.hero-sub {
  font-size: var(--text-xl);
  color: rgba(251, 251, 248, 0.88);
  max-width: 38rem;
  line-height: 1.5;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
}

.hero .btn-ghost {
  color: var(--paper);
  border-color: var(--paper);
}

.hero .btn-ghost:hover {
  color: var(--ink);
}

.hero-note {
  font-size: var(--text-sm);
  color: rgba(251, 251, 248, 0.7);
}

.hero-figure {
  margin-top: var(--space-7);
}

/* The slider and its tabs on the dark ground. */
.hero .ba {
  border-color: rgba(251, 251, 248, 0.3);
  box-shadow: 8px 8px 0 rgba(43, 60, 255, 0.9);
}

.hero .ba-caption {
  color: rgba(251, 251, 248, 0.7);
}

.hero .style-tab {
  border-color: rgba(251, 251, 248, 0.4);
  color: rgba(251, 251, 248, 0.85);
}

.hero .style-tab:hover {
  color: var(--paper);
}

.hero .style-tab.is-active {
  background: var(--paper);
  border-color: var(--paper);
  color: var(--ink);
}

/* Wide screens: pitch and card left, the full 4:3 slider right, both
   inside the first screen (the 1366x768 and 1280x800 laptops paid
   traffic arrives on). Three headline lines, not four, so the card
   finishes above the fold at 1280x800. */
@media (min-width: 960px) {
  .hero {
    padding-block: var(--space-7) var(--space-7);
  }

  .hero > .container {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    gap: var(--space-7);
    align-items: center;
  }

  .hero-inner {
    gap: var(--space-4);
  }

  .hero h1 {
    font-size: clamp(2.4rem, 1.3rem + 2.5vw, 3.5rem);
  }

  .hero-sub {
    font-size: var(--text-base);
    max-width: 30rem;
  }

  .hero-figure {
    margin-top: 0;
  }
}

/* On phones, tighten the hero so the slider peeks above the fold:
   cut-off content is the scroll cue. */
@media (max-width: 719px) {
  .hero {
    padding-block: var(--space-5) var(--space-5);
  }

  .hero-inner {
    gap: var(--space-4);
  }

  .hero-sub {
    font-size: var(--text-lg);
  }

  .hero-figure {
    margin-top: var(--space-5);
  }
}

/* Load-in stagger */

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.rise {
  animation: rise 700ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.rise-1 { animation-delay: 60ms; }
.rise-2 { animation-delay: 160ms; }
.rise-3 { animation-delay: 260ms; }
.rise-4 { animation-delay: 360ms; }
.rise-5 { animation-delay: 480ms; }

/* Steps strip */

.steps {
  border-block: 1px solid var(--line);
  background: var(--paper-deep);
}

.steps ol {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--space-5);
  padding-block: var(--space-6);
}

.steps li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-4);
  align-items: baseline;
}

.step-num {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  color: var(--accent);
}

.steps h3 {
  font-size: var(--text-lg);
  margin-bottom: var(--space-1);
}

.steps p {
  color: var(--ink-soft);
  font-size: var(--text-sm);
}

@media (min-width: 720px) {
  .steps ol {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-6);
  }

  .steps li:not(:first-child) {
    border-left: 1px solid var(--line-strong);
    padding-left: var(--space-6);
  }
}

/* Section scaffolding */

.section {
  /* Was space-9; tightened 2026-07-19 to pull the page's total height in. */
  padding-top: var(--space-8);
}

/* Mid-page CTA bands: the actionable elements between hero and pricing.
   A small top gap keeps each band attached to the section it answers. */

.cta-band-section {
  padding-top: var(--space-7);
}

.cta-band {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4) var(--space-6);
  border: var(--border-hard);
  border-radius: var(--radius-md);
  background: var(--paper-card);
  box-shadow: var(--shadow-soft);
  padding: var(--space-5) var(--space-6);
}

.cta-band-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  line-height: 1.15;
}

.cta-band-note {
  color: var(--ink-soft);
  font-size: var(--text-sm);
  margin-top: var(--space-1);
}

@media (max-width: 719px) {
  .cta-band {
    padding: var(--space-5);
  }

  .cta-band .btn {
    width: 100%;
  }
}

.section-head {
  max-width: 40rem;
  margin-bottom: var(--space-7);
  display: grid;
  gap: var(--space-3);
}

.section-head h2 {
  font-size: var(--text-h2);
}

.section-head p {
  color: var(--ink-soft);
  font-size: var(--text-lg);
}

/* Proof wall */

.proof-grid {
  display: grid;
  gap: var(--space-6) var(--space-5);
}

@media (min-width: 720px) {
  .proof-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.proof-card {
  display: grid;
  gap: var(--space-3);
}

.proof-card figcaption {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}

.proof-card figcaption strong {
  font-weight: 500;
  color: var(--ink);
}

.proof-card-wide {
  grid-column: 1 / -1;
  width: 100%;
  max-width: 46rem;
  justify-self: center;
}

/* Sticky mobile CTA */

.mobile-cta {
  display: none;
}

@media (max-width: 719px) {
  /* One piece of chrome at a time (owner call 2026-08-26): at phone
     widths the lander's header scrolls away with the hero instead of
     stacking with the fixed CTA bar below; the two were spending ~20%
     of the viewport carrying the same action. Scoped via the hero,
     which only the lander renders: desktop keeps the sticky header
     (no bar there), and app pages keep it at every width (the credit
     chip, and the workspace rail pins against --header-h). Relative
     rather than static since 2026-09-06: the hero now pulls up under
     it (below), and the header's z-index only holds it above the
     hero while it is positioned. Still not sticky. */
  body:has(main > .hero) .site-header {
    position: relative;
  }

  .mobile-cta {
    display: block;
    position: fixed;
    inset: auto 0 0 0;
    padding: var(--space-3) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom));
    background: linear-gradient(to top, var(--paper) 65%, transparent);
    z-index: 6;
    transform: translateY(110%);
    transition: transform 250ms ease;
    pointer-events: none;
  }

  .mobile-cta.is-visible {
    transform: none;
    pointer-events: auto;
  }

  .mobile-cta .btn {
    width: 100%;
  }

  .site-footer {
    padding-bottom: calc(var(--space-9) + env(safe-area-inset-bottom));
  }
}

/* Style catalog grid: one room, every style */

.catalog-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}

@media (min-width: 720px) {
  .catalog-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* The phone-only collapse (catalog_controller): the first eight tiles
   and a Show all button while .is-collapsible is on; the button never
   renders without JS or above phone width, so the wall is the default. */
.catalog-more {
  display: none;
}

@media (max-width: 719px) {
  .catalog.is-collapsible .catalog-grid > .tile-link:nth-child(n + 9) {
    display: none;
  }

  .catalog.is-collapsible .catalog-more {
    display: block;
    width: 100%;
    margin-top: var(--space-4);
  }
}

.catalog-tile {
  position: relative;
  border: var(--border-hard);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--paper-card);
}

.catalog-tile img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 250ms ease;
}

.catalog-tile:hover img {
  transform: scale(1.04);
}

.catalog-tile figcaption {
  position: absolute;
  left: var(--space-2);
  bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: rgba(16, 16, 16, 0.82);
  color: var(--paper);
  padding: 2px 8px;
  border-radius: var(--radius-sm);
}

/* Pricing */

.pricing {
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--radius-lg);
  padding: var(--space-8) var(--space-5);
  text-align: center;
  display: grid;
  justify-items: center;
  gap: var(--space-5);
  position: relative;
  overflow: hidden;
}

.pricing::before {
  content: "";
  position: absolute;
  inset: auto auto -55% -20%;
  width: 34rem;
  height: 34rem;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(43, 60, 255, 0.35), transparent 70%);
  pointer-events: none;
}

.pricing > * {
  position: relative;
}

.pricing .kicker {
  color: var(--accent-soft);
}

.pricing h2 {
  font-size: var(--text-h2);
  max-width: 24ch;
}

.pricing .hero-note {
  color: #8a8a82;
}

/* The ladder's trust and legal lines read as ink-soft on the light
   paywall; on this dark panel that lands near 2:1 contrast, so they
   take the hero-note's dark-panel tone (2026-08-25 mobile pass). */
.pricing .ladder-trust,
.pricing .ladder-fine {
  color: #8a8a82;
}

.pricing-free-note {
  color: #8a8a82;
  font-size: var(--text-sm);
}

.pricing-free-note a {
  color: var(--accent-soft);
}

.pricing-anchor {
  color: #a3a39b;
  max-width: 34rem;
}

.price-toggle {
  display: inline-flex;
  border: 1px solid #3d3d38;
  border-radius: var(--radius-pill);
  padding: 0.25rem;
  gap: 0.25rem;
}

.price-toggle-btn {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #a3a39b;
  background: transparent;
  border: none;
  border-radius: var(--radius-pill);
  padding: 0.55em 1.1em;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
}

.price-toggle-btn.is-active {
  background: var(--accent);
  color: #fff;
}

.price-toggle-save {
  font-size: 0.85em;
  color: var(--accent-soft);
}

.price-toggle-btn.is-active .price-toggle-save {
  color: #cdd3ff;
}

.plan-grid {
  display: grid;
  gap: var(--space-4);
  width: 100%;
  max-width: 60rem;
  text-align: left;
}

@media (min-width: 720px) {
  .plan-grid {
    grid-template-columns: repeat(3, 1fr);
    /* One shared card height; the feature list flexes below so every
       CTA pins to the same baseline (polish pass 2026-07-24). */
    align-items: stretch;
  }
}

.plan-card {
  background: var(--paper-card);
  color: var(--ink);
  border: var(--border-hard);
  border-radius: var(--radius-md);
  box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.55);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  position: relative;
}

.plan-card.is-featured {
  border: 2px solid var(--accent);
  box-shadow: 8px 8px 0 rgba(43, 60, 255, 0.65);
}

@media (min-width: 720px) {
  /* The featured card breaks the shared top line upward so the eye
     lands on Pro before it lands on a price. */
  .plan-card.is-featured {
    margin-top: calc(-1 * var(--space-3));
    padding-top: var(--space-6);
  }
}

.plan-tag {
  position: absolute;
  top: -0.85em;
  left: var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: var(--accent);
  color: #fff;
  padding: 0.2em 0.7em;
}

.plan-name {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
}

.plan-price {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 1.8rem + 2vw, 3.2rem);
  line-height: 1;
}

.plan-price small {
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--ink-soft);
}

.plan-note {
  font-size: var(--text-xs);
  font-family: var(--font-mono);
  color: var(--ink-soft);
  margin-top: calc(-1 * var(--space-2));
}

.plan-card ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--space-2);
  align-content: start;
  font-size: var(--text-sm);
  color: var(--ink-soft);
  /* The list absorbs the height difference between plans, pinning every
     CTA to the card's foot. */
  flex: 1;
}

.plan-card ul li {
  display: flex;
  gap: 0.55em;
  align-items: baseline;
}

.plan-card ul li::before {
  content: "\2713";
  flex: none;
  font-family: var(--font-mono);
  font-size: 0.8em;
  color: var(--accent);
}

/* The headline feature (the credit allowance) carries the row weight. */
.plan-card ul li:first-child {
  color: var(--ink);
  font-weight: 600;
}

.plan-cta {
  width: 100%;
  text-align: center;
  margin-top: var(--space-2);
}

/* FAQ */

.faq {
  display: grid;
  gap: var(--space-3);
}

.faq details {
  background: var(--paper-card);
  border: var(--border-hard);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
}

.faq summary {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-lg);
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: "+";
  font-family: var(--font-body);
  color: var(--accent);
  font-size: 1.4em;
  line-height: 1;
  transition: transform 200ms ease;
}

.faq details[open] summary::after {
  transform: rotate(45deg);
}

.faq details p {
  padding-top: var(--space-3);
  color: var(--ink-soft);
}

/* Subscribe placeholder page */

.placeholder-page {
  min-height: 55vh;
  display: grid;
  align-content: center;
  gap: var(--space-4);
  padding-block: var(--space-8);
}

.placeholder-page h1 {
  font-size: var(--text-h2);
}

.placeholder-page p {
  color: var(--ink-soft);
  font-size: var(--text-lg);
  max-width: 34rem;
}

/* The sign-in card in the hero (REVEAL.md decision 2, 2026-09-03):
   interiorai's arrangement in our card language. The options partial
   brings its own form styles from auth.css; this is the frame. */

.hero-start {
  width: min(24rem, 100%);
  background: var(--paper-card);
  border: var(--border-hard);
  border-radius: var(--radius-md);
  box-shadow: 8px 8px 0 var(--accent);
  padding: var(--space-5);
  display: grid;
  gap: var(--space-3);
}

.hero-start-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
}

.hero-start .auth-divider {
  margin: var(--space-1) 0;
}

.hero-start-fine {
  font-size: var(--text-xs);
  color: var(--ink-soft);
}

/* On phones the card is the first thing after the headline: the sub
   copy and the note move below it so the whole card sits in the first
   screen (REVEAL.md verification: 375x667). */
@media (max-width: 719px) {
  .hero-sub {
    order: 1;
  }

  .hero-note {
    order: 2;
  }
}

/* The tool proof wall (2026-09-03): the caption carries the tool's line
   icon in the grid's stroke, and the honesty line closes the section. */

.proof-card figcaption .tool-icon {
  width: 1rem;
  height: 1rem;
  vertical-align: -0.2em;
  margin-right: 0.4em;
  color: var(--ink);
}

/* The header over the hero (owner call 2026-09-03): on the homepage the
   wall runs up behind a transparent header while the hero is under it
   (hero_chrome_controller toggles body.is-over-hero), and the header
   returns to paper once the hero scrolls away. The hero pulls up under
   the sticky header by the header's height and pads the same amount,
   so nothing else moves. Phones get the same look (owner call
   2026-09-06, after the ink bar read as a band above the wall) with
   no observer: their header is not sticky and never leaves the hero's
   top, so it stays transparent for good. */

@media (min-width: 720px) {
  body:has(main > .hero) main > .hero {
    margin-top: calc(-1 * var(--hero-overlap, var(--header-h)));
    padding-top: calc(var(--space-8) + var(--hero-overlap, var(--header-h)));
  }

  body:has(main > .hero) .site-header {
    transition: background-color 220ms ease, border-color 220ms ease;
  }

  body.is-over-hero .site-header {
    background: transparent;
    border-bottom-color: transparent;
    backdrop-filter: none;
  }
}

@media (min-width: 960px) {
  body:has(main > .hero) main > .hero {
    padding-top: calc(var(--space-7) + var(--hero-overlap, var(--header-h)));
  }
}

@media (max-width: 719px) {
  body:has(main > .hero) .site-header {
    background: transparent;
    border-bottom-color: transparent;
    backdrop-filter: none;
  }

  /* The phone hero's own top padding (var(--space-5), set above) plus
     the overlap, the same arithmetic as the wide rule. */
  body:has(main > .hero) main > .hero {
    margin-top: calc(-1 * var(--hero-overlap, var(--header-h)));
    padding-top: calc(var(--space-5) + var(--hero-overlap, var(--header-h)));
  }
}

/* Header colors on the dark ground, shared by the phone's header (always
   over the hero) and the wide header while it is over the hero. */
body.is-over-hero .site-header .wordmark,
body.is-over-hero .site-header .wordmark:hover {
  color: var(--paper);
}

body.is-over-hero .site-header .wordmark em {
  color: var(--accent-soft);
}

body.is-over-hero .site-header .header-nav-link {
  color: rgba(251, 251, 248, 0.8);
}

body.is-over-hero .site-header .header-nav-link:hover {
  color: var(--paper);
}

body.is-over-hero .site-header .btn-ghost {
  color: var(--paper);
  border-color: rgba(251, 251, 248, 0.55);
}

body.is-over-hero .site-header .btn-ghost:hover {
  color: var(--ink);
  background: var(--paper);
  border-color: var(--paper);
}

/* The usage ring over the dark hero (owner report 2026-09-09: an ink
   track and IKB arc vanished against the wall). Paper strokes, the soft
   accent for the arc, the warn state in paper. */
body.is-over-hero .site-header .usage-chip {
  color: var(--paper);
  border-color: rgba(251, 251, 248, 0.55);
}

body.is-over-hero .site-header .usage-chip:hover {
  background: rgba(251, 251, 248, 0.12);
}

body.is-over-hero .site-header .usage-ring-track {
  stroke: rgba(251, 251, 248, 0.35);
}

body.is-over-hero .site-header .usage-ring-arc {
  stroke: var(--accent-soft);
}

body.is-over-hero .site-header .usage-chip.is-warn .usage-ring-arc,
body.is-over-hero .site-header .usage-chip.is-full .usage-ring-arc {
  stroke: var(--paper);
}

@media (max-width: 719px) {
  body:has(main > .hero) .site-header .wordmark,
  body:has(main > .hero) .site-header .wordmark:hover {
    color: var(--paper);
  }

  body:has(main > .hero) .site-header .wordmark em {
    color: var(--accent-soft);
  }

  body:has(main > .hero) .site-header .header-nav-link {
    color: rgba(251, 251, 248, 0.8);
  }

  body:has(main > .hero) .site-header .btn-ghost {
    color: var(--paper);
    border-color: rgba(251, 251, 248, 0.55);
  }

  body:has(main > .hero) .site-header .usage-chip {
    color: var(--paper);
  }

  body:has(main > .hero) .site-header .usage-ring-track {
    stroke: rgba(251, 251, 248, 0.35);
  }

  body:has(main > .hero) .site-header .usage-ring-arc {
    stroke: var(--accent-soft);
  }

  body:has(main > .hero) .site-header .usage-chip.is-warn .usage-ring-arc,
  body:has(main > .hero) .site-header .usage-chip.is-full .usage-ring-arc {
    stroke: var(--paper);
  }
}

/* The tool wall's caption icons draw themselves in one stroke when the
   section scrolls into view (draw controller, 2026-09-03). Paths carry
   pathLength="1", so the dash is the whole path; the hide exists only
   under .will-draw, which the controller sets, so plain icons render
   without it. Each card draws as it enters the viewport; sub-strokes
   follow each other, cards arriving together follow each other. */

/* One left-aligned row under each slider: icon, tool, result (owner:
   the icon sat on the left while the label centered underneath). */
.proof-card figcaption {
  display: flex;
  align-items: center;
  gap: 0.55em;
  text-align: left;
}

.proof-card figcaption .tool-icon {
  flex: none;
  width: 1.1rem;
  height: 1.1rem;
  margin: 0;
}

.proof-card .tool-icon :is(path, rect, circle, line, polyline, polygon) {
  stroke-dasharray: 1;
}

.will-draw .proof-card .tool-icon :is(path, rect, circle, line, polyline, polygon) {
  stroke-dashoffset: 1;
}

.will-draw .proof-card.is-drawn .tool-icon :is(path, rect, circle, line, polyline, polygon) {
  animation: icon-draw 700ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  animation-delay: var(--draw-delay, 0ms);
}

.will-draw .proof-card.is-drawn .tool-icon :is(path, rect, circle, line, polyline, polygon):nth-child(2) {
  animation-delay: calc(var(--draw-delay, 0ms) + 160ms);
}

.will-draw .proof-card.is-drawn .tool-icon :is(path, rect, circle, line, polyline, polygon):nth-child(3) {
  animation-delay: calc(var(--draw-delay, 0ms) + 320ms);
}

.will-draw .proof-card.is-drawn .tool-icon :is(path, rect, circle, line, polyline, polygon):nth-child(n + 4) {
  animation-delay: calc(var(--draw-delay, 0ms) + 480ms);
}

@keyframes icon-draw {
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .will-draw .proof-card .tool-icon :is(path, rect, circle, line, polyline, polygon) {
    stroke-dashoffset: 0;
    animation: none;
  }
}
