@import url('assets/fonts.css');
@import url('assets/tokens.css');

/* ============================================================================
   Sonata kit reference: the brand rendering itself.

   Every value here resolves to a kit token. Type comes from the ramp, colour
   from the palette, spacing from the 4px scale, shadows from the named effect
   set, motion from the choreography file. White stays dominant and Cosmic
   Latte stays sparing, so the page holds the proportion rule at page scale.

   The page is read as a gallery. The wall is white and nearly silent, the
   chrome sits back, and the only things allowed to carry weight are the
   specimens themselves. Prose is set on the wall, never in a box: a box is
   reserved for something that is actually a component.
   ============================================================================ */

:root {
  /* Fluid type. The desktop end of each clamp is the ramp value; the floor is
     the step below it, so the ramp degrades onto itself rather than onto
     arbitrary sizes. */
  --t-display: clamp(40px, 6.4vw, 64px);
  --t-h1: clamp(32px, 4.4vw, 48px);
  --t-h2: clamp(28px, 3.2vw, 40px);
  --t-h3: clamp(24px, 2.4vw, 32px);
  --t-h4: clamp(20px, 1.8vw, 24px);
  --t-h5: 20px;
  --t-h6: clamp(20px, 1.8vw, 24px);
  --t-body: 14px;
  --t-lead: clamp(16px, 1.4vw, 20px);

  --page-margin: clamp(24px, 7vw, 128px);

  /* Three rhythms, and the page uses only these three. --gutter sits between
     two things of the same kind, --group between two groups of specimens, and
     --room between one section and the next. */
  --gutter: 24px;
  --group: clamp(48px, 6vw, 96px);
  --room: clamp(96px, 13vw, 200px);

  --rail: 216px;

  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-enter: cubic-bezier(0, 0, 0.2, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);
  --ease-bloom: cubic-bezier(0.33, 0, 0.15, 1);
  --dur-instant: 120ms;
  --dur-quick: 200ms;
  --dur-base: 320ms;
  --dur-slow: 560ms;
  --dur-bloom: 1200ms;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 24px;
}

body {
  margin: 0;
  background: var(--white);
  color: var(--black-900);
  font-family: var(--font-sans), system-ui, sans-serif;
  font-size: var(--t-body);
  line-height: 20px;
  -webkit-font-smoothing: antialiased;
}

/* ── type roles ─────────────────────────────────────────────────────────── */

h1, h2, h3, h4, h5 {
  font-family: var(--font-display), Georgia, serif;
  font-weight: 400;
  letter-spacing: -0.02em;
  margin: 0;
}

.display { font-size: var(--t-display); line-height: 1; }
h1 { font-size: var(--t-h1); line-height: 1.04; }
h2 { font-size: var(--t-h2); line-height: 1.05; }
h3 { font-size: var(--t-h3); line-height: 1.12; }
h4 { font-size: var(--t-h4); line-height: 1.08; }
h5 { font-size: var(--t-h5); line-height: 1.1; }

/* The italic rule: it falls on the possessive adjective, nothing else. */
em, .poss {
  font-style: italic;
  font-family: var(--font-display), Georgia, serif;
}

.eyebrow {
  font-family: var(--font-mono), ui-monospace, monospace;
  font-size: 11px;
  line-height: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gray-500);
  margin: 0;
}

.lead {
  font-size: var(--t-lead);
  line-height: 1.5;
  max-width: 58ch;
  color: inherit;
}

p { margin: 0; max-width: 62ch; }
.muted { color: var(--gray-700); }
.mono {
  font-family: var(--font-mono), ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.05em;
}

a { color: inherit; }

/* ── shell ──────────────────────────────────────────────────────────────── */

.shell { display: flex; align-items: flex-start; }

/* The rail is chrome, so it is the quietest surface on the page: no border, no
   fill, and a type colour a step lighter than the body. */
.rail {
  position: sticky;
  top: 0;
  width: var(--rail);
  height: 100vh;
  flex: 0 0 var(--rail);
  padding: 40px 24px 32px 32px;
  display: flex;
  flex-direction: column;
  gap: 32px;
  background: var(--white);
  z-index: 20;
}

.rail__mark img { height: 18px; display: block; opacity: 0.85; }

.rail nav { display: flex; flex-direction: column; gap: 20px; overflow-y: auto; }
.rail__group { display: flex; flex-direction: column; gap: 2px; }
.rail__group .eyebrow { margin-bottom: 6px; color: var(--gray-300); }

/* The current section is marked with a rule in the margin rather than a weight
   change, so nothing in the rail ever gets darker than the work beside it. */
.rail__link {
  position: relative;
  font-size: 12px;
  line-height: 22px;
  color: var(--gray-500);
  text-decoration: none;
  transition: color var(--dur-quick) var(--ease-standard);
}
.rail__link::before {
  content: "";
  position: absolute;
  left: -14px;
  top: 50%;
  width: 6px;
  height: 1px;
  background: var(--black-900);
  transform: translateY(-50%) scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-quick) var(--ease-standard);
}
.rail__link:hover { color: var(--gray-800); }
.rail__link.is-current { color: var(--black-900); }
.rail__link.is-current::before { transform: translateY(-50%) scaleX(1); }


.rail__toggle {
  display: none;
  font-family: var(--font-mono), monospace;
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: none;
  border: 0.5px solid var(--gray-200);
  border-radius: 999px;
  padding: 6px 14px;
  cursor: pointer;
}

main { flex: 1; min-width: 0; }

/* ── sections ───────────────────────────────────────────────────────────── */

/* No dividing rule between sections. The space is the divider. */
section {
  padding: var(--room) var(--page-margin);
  position: relative;
}

/* Two rooms on the page are dark, and they are the only two. Everything else
   is the white wall. */
.band-black {
  background-image: var(--gradient-black);
  color: var(--white);
}
.band-black .eyebrow { color: var(--gray-500); }
.band-black .muted { color: var(--gray-400); }

.section-head {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin-bottom: var(--group);
  max-width: 62ch;
}
.section-head .eyebrow { margin-bottom: 4px; }
.section-head .lead { color: var(--gray-800); }
.band-black .section-head .lead { color: var(--gray-300); }

/* The gap between specimen groups is the room's own rhythm, not a card gap. */
.stack { display: flex; flex-direction: column; gap: var(--group); }
.stack-s { display: flex; flex-direction: column; gap: 12px; }

.grid { display: grid; gap: var(--gutter); }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* A specimen grid breathes wider than a text grid. */
.grid--wide { gap: 40px 32px; }

/* Prose on the wall. A caption, a point of view, a note beside the work: none
   of these are components, so none of them get a box. */
.note { display: flex; flex-direction: column; gap: 10px; max-width: 44ch; }
.note h4, .note h5 { margin-bottom: 2px; }

/* A caption under a specimen. Mono, small, and the same on every specimen so
   the eye can skip the whole layer when it wants to. */
.caption {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-mono), monospace;
  font-size: 11px;
  letter-spacing: 0.05em;
  color: var(--gray-600);
}
.caption__spec { color: var(--gray-400); }
.band-black .caption { color: var(--gray-400); }
.band-black .caption__spec { color: var(--gray-600); }

/* ── hero ───────────────────────────────────────────────────────────────── */

.hero {
  min-height: min(82vh, 820px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
}

.hero__inner { position: relative; z-index: 2; display: flex; flex-direction: column; gap: 24px; }

/* The signature move. The flower enters full and resolves into the ground it
   sits on, then holds there. It runs once, on load, and never loops. */
.hero__flower {
  position: absolute;
  right: -6%;
  top: 50%;
  width: min(52vw, 720px);
  transform: translateY(-50%) scale(1);
  filter: blur(0px);
  opacity: 0.7;
  z-index: 1;
  pointer-events: none;
  animation: flower-to-field var(--dur-bloom) var(--ease-bloom) 400ms forwards;
}

@keyframes flower-to-field {
  0%   { transform: translateY(-50%) scale(1);   filter: blur(0px);   opacity: 0.7; }
  55%  { transform: translateY(-50%) scale(1.6); filter: blur(40px);  opacity: 0.6; }
  100% { transform: translateY(-50%) scale(2.8); filter: blur(120px); opacity: 0.5; }
}

.hero__flower img { width: 100%; display: block; }

/* Stage three of the editing formula: the Cosmic Latte overlay. It is what
   pulls the flower's blues back toward the brand's warmth. */
.hero__flower::after {
  content: "";
  position: absolute;
  inset: -10%;
  background: var(--cosmic-latte-100);
  mix-blend-mode: overlay;
  pointer-events: none;
}

/* ── copy affordance ────────────────────────────────────────────────────── */

/* Anything carrying a value can be lifted off the page. The affordance stays
   invisible until the pointer is on the specimen, so the resting page is still
   just the work. */
.copy {
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: copy;
  position: relative;
  display: block;
  width: 100%;
}
.copy:focus-visible { outline: 1px solid var(--azure-400); outline-offset: 4px; }
.copy--stack { display: flex; flex-direction: column; gap: 12px; }
.copy--stack .caption { justify-content: space-between; }

.copy__hint {
  font-family: var(--font-mono), monospace;
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gray-400);
  opacity: 0;
  transition: opacity var(--dur-quick) var(--ease-standard);
}
.copy:hover .copy__hint,
.copy:focus-visible .copy__hint { opacity: 1; }
.copy.is-copied .copy__hint { opacity: 1; color: var(--black-900); }

.band-black .copy.is-copied .copy__hint { color: var(--white); }

/* One toast, bottom left, out of the way of the work. */
.toast {
  position: fixed;
  left: calc(var(--rail) + 24px);
  bottom: 24px;
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 16px;
  border-radius: 999px;
  background-image: var(--gradient-black);
  color: var(--white);
  font-family: var(--font-mono), monospace;
  font-size: 11px;
  letter-spacing: 0.05em;
  box-shadow: var(--shadow-drop-shadow);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity var(--dur-quick) var(--ease-standard),
              transform var(--dur-quick) var(--ease-enter);
}
.toast.is-up { opacity: 1; transform: none; }

/* ── specimens ──────────────────────────────────────────────────────────── */

/* A swatch is a chip on the wall with a caption under it. No frame, because a
   frame around a colour is a second colour. */
.swatch { display: block; }
.swatch__chip {
  height: 132px;
  display: block;
  border-radius: 10px;
  transition: transform var(--dur-quick) var(--ease-standard),
              box-shadow var(--dur-quick) var(--ease-standard);
}
/* Only a chip that would otherwise vanish into the wall gets a hairline. */
.swatch__chip--pale { box-shadow: inset 0 0 0 0.5px var(--gray-200); }
.copy:hover .swatch__chip { box-shadow: var(--shadow-soft-shadow), inset 0 0 0 0.5px var(--gray-200); }

.swatch__meta { padding: 12px 2px 0; display: flex; flex-direction: column; gap: 3px; }
.swatch__name { font-size: 12px; line-height: 16px; display: block; }
.swatch__hex {
  font-family: var(--font-mono), monospace;
  font-size: 10px;
  line-height: 14px;
  letter-spacing: 0.05em;
  color: var(--gray-500);
  text-transform: uppercase;
  display: block;
}
.swatch__foot { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }

/* A card is a component, so it keeps its frame. */
.card {
  background: var(--white);
  border: 0.5px solid var(--gray-100);
  border-radius: 16px;
  padding: 24px;
  box-shadow: var(--shadow-soft-shadow);
}

.ramp-row {
  display: grid;
  grid-template-columns: 108px 1fr auto;
  gap: 32px;
  align-items: baseline;
  padding: 24px 0;
  border-top: 0.5px solid var(--gray-100);
}
.ramp-row:first-child { border-top: 0; }
.ramp-spec { font-family: var(--font-mono), monospace; font-size: 10px; letter-spacing: 0.05em; color: var(--gray-400); white-space: nowrap; }
.ramp-row .copy__hint { position: absolute; right: 0; top: -14px; }

/* A pedestal: the neutral ground a white specimen needs in order to be seen at
   all. Latte earns its place here, and only here. */
.pedestal {
  background: var(--cosmic-latte-25);
  border-radius: 16px;
  padding: clamp(32px, 4vw, 56px);
}

.logo-tile {
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 56px 24px;
  min-height: 180px;
  background: var(--gray-50);
}
.logo-tile img { max-width: 70%; height: auto; }
.logo-tile.on-dark { background-image: var(--gradient-black); }
.logo-tile.on-latte { background: var(--cosmic-latte-100); }

.flower-tile {
  border-radius: 12px;
  overflow: hidden;
  background: var(--cosmic-latte-25);
  aspect-ratio: 4 / 5;
  display: flex;
  align-items: center;
  justify-content: center;
}
.flower-tile img { width: 78%; opacity: 0.7; }
.flower-tile.is-blurred img { filter: blur(24px); transform: scale(1.25); }
.flower-tile.is-field img { filter: blur(60px); transform: scale(1.9); opacity: 0.55; }

/* ── component specimens ────────────────────────────────────────────────── */

.spec {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
}

.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 28px;
  padding: 0 16px;
  border-radius: 999px;
  font-family: var(--font-mono), monospace;
  font-size: 13px;
  line-height: 14px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: inset 0 0 5px 0 rgba(255, 255, 255, 0.3);
}
.badge--default { background: var(--black-900); color: var(--white); }
.badge--ghost { background: var(--gray-200); }
.badge--lavender { background: var(--lavender-300); }
.badge--mint { background: var(--mint-300); }
.badge--coral { background: var(--coral-300); }
.badge--azure { background: var(--azure-300); }
.badge--gradient { background-image: var(--gradient-soft-2); }
.badge--outlined { border: 0.5px solid var(--gray-800); box-shadow: none; }
.badge--ai { background: var(--cosmic-latte-50); box-shadow: var(--shadow-ai-glow); border: 0.5px solid #ff9484; }
.badge--frosted { background: var(--white-50); backdrop-filter: blur(25px); box-shadow: 0 0 20px 0 rgba(0,0,0,0.08); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  padding: 0 32px;
  border-radius: 999px;
  border: 0;
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--dur-quick) var(--ease-standard),
              color var(--dur-quick) var(--ease-standard),
              box-shadow var(--dur-quick) var(--ease-standard);
}
.btn--black {
  background-image: var(--gradient-black);
  color: var(--white);
  box-shadow: inset 0 -2px 6px 0 rgba(255,255,255,0.25);
}
.btn--black:hover { background-image: none; background-color: var(--gray-800); }
.btn--white { background: var(--white-80); color: var(--black-900); box-shadow: var(--shadow-drop-shadow); }
.btn--white:hover { background: var(--white); }
.btn--outlined { background: transparent; border: 0.5px solid var(--gray-700); color: var(--black-900); }
.btn--outlined:hover { background-image: var(--gradient-black); color: var(--white); border-color: transparent; }
.btn--lg { height: 62px; font-size: 20px; }
.btn:active { transform: translateY(1px); transition-duration: var(--dur-instant); }

/* The state strip renders rest, hover, focus and disabled at once, so a state
   can be read without being reproduced. */
.states { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--gutter); }
.state { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.state > .btn { pointer-events: none; }
.btn.is-hover { background-image: none; background-color: var(--gray-800); }
.btn.is-focus { outline: 2px solid var(--azure-400); outline-offset: 2px; }
.btn.is-disabled { opacity: 0.4; }

.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 360px;
}
.field label { font-size: 12px; line-height: 16px; font-weight: 500; padding: 0 8px; }
.field input {
  border-radius: 999px;
  border: 0.5px solid rgba(0, 0, 0, 0.1);
  background: var(--white-80);
  padding: 10px 16px;
  font-family: var(--font-mono), monospace;
  font-size: 12px;
  color: var(--gray-800);
  outline: none;
  transition: border-color var(--dur-quick) var(--ease-standard),
              box-shadow var(--dur-quick) var(--ease-standard);
}
.field input:focus { border-color: var(--azure-400); box-shadow: var(--shadow-empty-field); }

.numbullet {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  font-family: var(--font-mono), monospace;
  font-size: 10px;
  letter-spacing: 0.05em;
  box-shadow: inset 0 0 7.5px 0 rgba(255,255,255,0.5);
}

.effect-tile {
  display: block;
  height: 140px;
  border-radius: 8px;
  background: var(--white);
}
.effect-tile--drop { box-shadow: var(--shadow-drop-shadow); }
.effect-tile--card { box-shadow: var(--shadow-card-shadow); border: 0.5px solid var(--gray-100); }
.effect-tile--marcomm { box-shadow: var(--shadow-marcomm-card-shadow); border: 0.5px solid var(--white-80); }
.effect-tile--soft { box-shadow: var(--shadow-soft-shadow); }
.effect-tile--ai { box-shadow: var(--shadow-ai-glow); border: 0.5px solid #ff9484; }
.effect-tile--inner { background-image: var(--gradient-black); box-shadow: var(--shadow-inner-shadow); }
.effect-tile--empty { box-shadow: var(--shadow-empty-field); }

/* ── motion lab ─────────────────────────────────────────────────────────── */

/* Each named transition renders as a specimen that actually runs it, at the
   duration and easing the choreography file states. Hovering plays it, and so
   does the replay control, so the move can be watched as many times as it
   takes. */
.motion-cell {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* The stage is a recess in the dark wall, not a lit panel: the specimen is the
   thing that should carry light. */
.motion-stage {
  position: relative;
  height: 132px;
  border-radius: 12px;
  background: var(--black-900-50);
  box-shadow: var(--shadow-inner-shadow);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  cursor: pointer;
}

.motion-actor {
  width: 64px;
  height: 40px;
  border-radius: 999px;
  background-image: var(--gradient-soft-2);
}

/* Hover and press hold their end state while the pointer is down on them, so
   they stay transitions. Every other move plays out and returns, so it is a
   keyframe animation and the cell is never sitting on an empty stage. */
.motion-cell[data-move="hover"] .motion-actor {
  transition: background-image var(--dur-quick) var(--ease-standard),
              box-shadow var(--dur-quick) var(--ease-standard);
}
.motion-cell[data-move="hover"].is-playing .motion-actor {
  background-image: var(--gradient-warm-peach);
  box-shadow: var(--shadow-drop-shadow);
}

.motion-cell[data-move="press"] .motion-actor {
  transition: transform var(--dur-instant) var(--ease-exit);
}
.motion-cell[data-move="press"].is-playing .motion-actor { transform: scale(0.94); }

.motion-cell[data-move="reveal"].is-playing .motion-actor {
  animation: m-reveal var(--dur-base) var(--ease-enter);
}
@keyframes m-reveal {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}

.motion-cell[data-move="dismiss"].is-playing .motion-actor {
  animation: m-dismiss var(--dur-quick) var(--ease-exit);
}
@keyframes m-dismiss {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* Expand is a panel opening, so its actor is a panel rather than a pill. */
.motion-cell[data-move="expand"] .motion-actor { height: 72px; width: 148px; border-radius: 10px; }
.motion-cell[data-move="expand"].is-playing .motion-actor {
  animation: m-expand var(--dur-base) var(--ease-standard);
}
@keyframes m-expand {
  from { height: 12px; opacity: 0.4; }
  to   { height: 72px; opacity: 1; }
}

/* The stagger specimen is a list, so its actor is a list. */
.motion-cell[data-move="stagger"] .motion-stage { flex-direction: column; gap: 8px; padding: 20px; }
.motion-cell[data-move="stagger"] .motion-bar {
  width: 100%;
  height: 8px;
  border-radius: 999px;
  background: var(--lavender-300);
}
.motion-cell[data-move="stagger"].is-playing .motion-bar {
  animation: m-reveal var(--dur-base) var(--ease-enter) backwards;
}

/* The signature move, at specimen scale, on demand. */
.motion-cell[data-move="signature"] .motion-stage { background: var(--cosmic-latte-25); }
.motion-cell[data-move="signature"] .motion-actor {
  width: 84px;
  height: 84px;
  border-radius: 0;
  background: none;
}
.motion-cell[data-move="signature"] .motion-actor img { width: 100%; display: block; opacity: 0.7; }
.motion-cell[data-move="signature"].is-playing .motion-actor {
  animation: flower-to-field-mini var(--dur-bloom) var(--ease-bloom) forwards;
}

@keyframes flower-to-field-mini {
  0%   { transform: scale(1);   filter: blur(0px);  opacity: 0.7; }
  55%  { transform: scale(1.6); filter: blur(12px); opacity: 0.6; }
  100% { transform: scale(2.8); filter: blur(34px); opacity: 0.5; }
}

.motion-meta { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.motion-replay {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-mono), monospace;
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--gray-500);
  transition: color var(--dur-quick) var(--ease-standard);
}
.motion-replay:hover { color: var(--white); }

/* ── tokens ─────────────────────────────────────────────────────────────── */

.token-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono), monospace;
  font-size: 11px;
  letter-spacing: 0.03em;
}
.token-table th, .token-table td {
  text-align: left;
  padding: 9px 12px;
  border-top: 0.5px solid var(--gray-100);
  white-space: nowrap;
}
.token-table th { color: var(--gray-500); text-transform: uppercase; font-weight: 400; }
.token-table tbody tr { cursor: copy; transition: background-color var(--dur-quick) var(--ease-standard); }
.token-table tbody tr:hover { background: var(--cosmic-latte-25); }
.token-table tbody tr.is-copied { background: var(--cosmic-latte-50); }
.token-table .swatch-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  vertical-align: -1px;
  margin-right: 8px;
  box-shadow: inset 0 0 0 0.5px var(--gray-200);
}
.token-scroll { overflow-x: auto; }

/* ── reveal ─────────────────────────────────────────────────────────────── */

/* The hidden start state is applied only once the script is running. Without
   it the page is fully readable, rather than a column of invisible sections. */
.js .reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--dur-base) var(--ease-enter),
              transform var(--dur-base) var(--ease-enter);
}
.js .reveal.is-in { opacity: 1; transform: none; }

/* ── responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
  .shell { flex-direction: column; }
  .rail {
    position: sticky;
    top: 0;
    width: 100%;
    height: auto;
    flex: none;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    padding: 16px var(--page-margin);
    gap: 16px;
    border-bottom: 0.5px solid var(--gray-100);
  }
  .rail__toggle { display: inline-block; }
  .rail nav { display: none; width: 100%; }
  .rail nav.is-open { display: flex; flex-direction: row; flex-wrap: wrap; gap: 20px; }
  .g3, .g4, .states { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero__flower { right: -30%; width: 90vw; opacity: 0.5; }
  .toast { left: 24px; }
}

@media (max-width: 560px) {
  .g2, .g3, .g4, .states { grid-template-columns: minmax(0, 1fr); }
  .ramp-row { grid-template-columns: 1fr; gap: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  /* Hold the end state rather than animating into it. */
  .hero__flower {
    animation: none;
    transform: translateY(-50%) scale(2.8);
    filter: blur(120px);
    opacity: 0.5;
  }
  /* The specimens rest in their end state either way, so reduced motion only
     has to take the travel out. */
  .motion-cell .motion-actor,
  .motion-cell .motion-bar {
    animation: none !important;
    transition-duration: var(--dur-quick) !important;
  }
}
