/* ===========================================================
   web-design-showcase.css — the six-language design showcase

   A tabbed frame that renders six fictional brands in six design
   languages. Lives on /services/web-design/.

   Kept out of web-design.css deliberately: that file's banner covers
   the hero, the portfolio cards and the empty state, and this is a
   large enough component that appending it would make the showcase
   most of a file claiming otherwise. Separate file also means
   a1_asset()'s mtime cache-bust only invalidates this while the demos
   are being tuned, and the whole section can be reverted by dropping
   one entry from $page_css / $page_js.

   Loads AFTER web-design.css so .wds-* never has to fight .wd-* on
   specificity.

   NO @layer anywhere. Nothing else on this site is layered, and
   unlayered styles beat all layered ones regardless of specificity —
   a layered sheet here would fall below base.css's h1-h4 rules.

   Colour: no literals in this file. Everything routes through the
   fenced --wds-* block in tokens.css via --wds-accent and the surface
   variables, so there is exactly one place to audit.
   =========================================================== */

.wds { position: relative; }

/* -----------------------------------------------------------
   Index rail
   Modelled on .co-tl-years (company.css:160): flex 1 1 0 so six
   labels can never overflow at any width without scrolling or
   wrapping. This matters more than it looks — the hero's right
   column is only 371px at the 901px breakpoint, which is 61px per
   tab. Sector-length labels ("Real Estate", "E-commerce") do not
   fit there, which is why the tabs are named for design languages
   instead and the sector is carried in the caption.
   ----------------------------------------------------------- */
.wds-rail {
  display: flex;
  border: 1px solid var(--rule-strong);
  border-bottom: 0;
  background: var(--paper);
}
.wds-tab {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  padding: 11px 4px 10px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gray-soft);
  background: none;
  border: 0;
  cursor: pointer;
  transition: color 0.2s var(--ease-out), background 0.2s var(--ease-out);
}
.wds-tab + .wds-tab { border-left: 1px solid var(--rule); }
.wds-tab:hover { color: var(--gray-deep); background: var(--bone); }

/* Tick above each tab — a second, non-colour signal for the active
   state (DESIGN.md: colour is never the only signal). */
.wds-tab::before {
  content: '';
  position: absolute; top: 0; left: 50%;
  width: 1px; height: 5px;
  background: var(--line-muted);
  transform: translateX(-50%);
  transition: height 0.2s var(--ease-out), background 0.2s var(--ease-out);
}
.wds-tab.is-current { color: var(--gray-deep); background: var(--bone); }
.wds-tab.is-current::before { height: 9px; background: var(--orange); }

/* The active marker reaches INTO the frame rather than sharing its
   border. The reference joins the tab's bottom border to the frame,
   which only works for a single non-wrapping row; a pseudo-element
   is free of that constraint. */
.wds-tab.is-current::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--orange);
}
.wds-tab:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }

/* -----------------------------------------------------------
   Frame + stage
   ----------------------------------------------------------- */
.wds-frame {
  border: 1px solid var(--rule-strong);
  background: var(--paper);
  box-shadow: 8px 8px 0 color-mix(in srgb, var(--gray-deep) 6%, transparent);
}
.wds-chrome {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--rule);
}
.wds-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--bone-deep); flex: 0 0 auto; }
.wds-url {
  flex: 1; min-width: 0; margin-left: 8px;
  padding: 4px 9px;
  background: var(--bone);
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: 0.04em;
  color: var(--line-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 7:5, not 16:10. The extra height is what lets a full-width globe sit
   under a full text stack. At 16:10 the two fight: sizing the globe to
   span the frame pushes its visible cap north of every city the nodes
   sit on, and shrinking it to fix that leaves gutters either side. */
.wds-stage {
  position: relative;
  overflow: hidden;
  aspect-ratio: 7 / 5;
  container-type: inline-size;   /* precedent: page.css:886 .conv-anim */
  background: var(--wds-surface);
  transition: background 0.45s var(--ease-out);

  /* Master scale for everything inside a demo. Sizing straight off cqw makes
     the mock grow with its container, so expanding the frame renders the same
     site ZOOMED rather than bigger — a 40px headline becomes 76px and it reads
     as a magnifying glass, not a wider browser. Capping at 7.5px means the
     mock stops growing once the frame passes ~750px and instead gains margin,
     which is what a real site does on a wide monitor. */
  --wds-s: min(1cqw, 7.5px);
}
.wds-panel { position: absolute; inset: 0; }

/* Ship this rule from the first commit. If a panel ever picks up
   display:flex or grid it beats the UA's [hidden]{display:none} and all
   six render on top of each other — the standard failure mode of every
   hand-rolled tab component. */
.wds-panel[hidden] { display: none !important; }

.wds-cap {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 9px 12px;
  border-top: 1px solid var(--rule);
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--line-muted);
}
.wds-cap b { color: var(--gray-soft); font-weight: 500; }

/* -----------------------------------------------------------
   Expand
   The frame defaults to the hero's right column, which is 668px at
   most. The demos reward more room, so the chrome bar carries an
   expand control — where a real browser puts one, which is both
   discoverable and thematically right on a page about interactive work.
   ----------------------------------------------------------- */
.wds-expand {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 6px;
  margin-left: 8px; padding: 4px 8px;
  font-family: var(--font-mono);
  font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gray-soft);
  background: none;
  border: 1px solid var(--rule);
  border-radius: 3px;
  cursor: pointer;
  transition: color 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}
.wds-expand:hover { color: var(--gray-deep); border-color: var(--rule-strong); }
.wds-expand:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.wds-expand svg { width: 10px; height: 10px; flex: 0 0 auto; }
.wds-expand .wds-x-close { display: none; }
.wds.is-expanded .wds-expand .wds-x-open  { display: none; }
.wds.is-expanded .wds-expand .wds-x-close { display: inline; }

/* Backdrop. A sibling rather than a pseudo-element so it can sit below the
   frame while the frame keeps its own stacking context. */
.wds-scrim {
  position: fixed; inset: 0; z-index: 90;
  background: color-mix(in srgb, var(--ink) 82%, transparent);
  opacity: 0;
  transition: opacity 0.28s var(--ease-out);
}
.wds.is-expanded ~ .wds-scrim,
.wds-scrim.is-on { opacity: 1; }

/* Expanded frame.
   Deliberately NOT the Fullscreen API: iOS Safari does not support it for
   arbitrary elements, and the jump out of the page is jarring for something
   that is meant to read as a window in the page.
   Deliberately NOT a body scroll lock either: hard rule 6 forbids
   overflow:hidden on html/body because it breaks the case study's sticky
   scroll. A full-viewport fixed overlay hides the page behind it anyway,
   and overscroll-behavior stops the scroll chaining out. */
.wds.is-expanded {
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column;
  padding: clamp(12px, 2.5vw, 40px);
  overscroll-behavior: contain;
}
.wds.is-expanded .wds-frame {
  flex: 1 1 auto;
  display: flex; flex-direction: column;
  min-height: 0;                 /* let the stage actually shrink in flex */
  max-width: 1600px;
  width: 100%;
  margin: 0 auto;
  box-shadow: none;
}
/* Drop the fixed ratio — the stage takes whatever height is left, so the
   frame matches the viewport instead of forcing a 7:5 box 970px tall. */
.wds.is-expanded .wds-stage {
  aspect-ratio: auto;
  flex: 1 1 auto;
  min-height: 0;
}
.wds.is-expanded .wds-rail { max-width: 1600px; width: 100%; margin: 0 auto; }

@media (prefers-reduced-motion: reduce) {
  .wds-scrim { transition: none; }
}

/* Progressive enhancement (hard rule 5). The rail is inert until
   js/web-design-showcase.js adds .is-live, but it still reserves its
   height, so upgrading costs zero layout shift. visibility:hidden also
   takes the buttons out of the tab order, so with JS off there are no
   dead controls — one demo renders, statically. */
.wds:not(.is-live) .wds-rail { visibility: hidden; }
.wds:not(.is-live) .wds-panel:not(:first-of-type) { display: none; }

/* ===========================================================
   FLOW — fintech
   =========================================================== */
.f-site { position: absolute; inset: 0; overflow: hidden; }

/* The canvas fills the stage and the globe's size/position come from
   the view matrix instead. Sizing an oversized square canvas and
   cropping it with overflow was the first approach and it was worse on
   every axis: the buffer held ~5x the pixels ever shown, and
   IntersectionObserver ratios measured against the canvas's own area
   stopped corresponding to anything on screen — the globe silently
   never started. */
.f-canvas   { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.f-fallback { position: absolute; inset: 0; width: 100%; height: 100%; display: none; }
.wds-panel.no-gl .f-canvas   { display: none; }
.wds-panel.no-gl .f-fallback { display: block; }

/* Everything below is expressed as multiples of --wds-s, never raw cqw, so
   the whole mock scales as one system and stops growing together. */
.f-nav {
  position: absolute; top: 0; left: 0; right: 0; z-index: 2;
  display: flex; align-items: center; gap: calc(2 * var(--wds-s));
  padding: calc(3.4 * var(--wds-s)) calc(4 * var(--wds-s));
}
.f-brand { font-weight: 800; font-size: calc(2.9 * var(--wds-s)); letter-spacing: -0.02em; color: var(--wds-ink); }
.f-links {
  display: flex; gap: calc(2.4 * var(--wds-s)); margin: 0 auto;
  padding: calc(1 * var(--wds-s)) calc(2 * var(--wds-s)); border-radius: 99px;
  background: color-mix(in srgb, var(--wds-ink) 7%, transparent);
}
.f-links span { font-size: calc(1.9 * var(--wds-s)); color: var(--wds-ink-dim); }
.f-auth { display: flex; gap: calc(1 * var(--wds-s)); }
.f-pill {
  font-size: calc(1.9 * var(--wds-s));
  padding: calc(1 * var(--wds-s)) calc(2.2 * var(--wds-s));
  border-radius: 99px;
  border: 1px solid var(--wds-hair); color: var(--wds-ink-dim);
}
.f-pill.solid { background: var(--wds-ink); color: var(--wds-surface); border-color: var(--wds-ink); }

/* Tight on purpose: every unit saved above is a unit of globe below, and the
   globe needs enough height for its curvature to read as a sphere rather than
   a textured plane. */
.f-body {
  position: absolute; top: calc(10 * var(--wds-s)); left: 0; right: 0; z-index: 2;
  padding: 0 calc(6 * var(--wds-s)); text-align: center;
}
/* 21ch — the headline must break to two lines, not three. */
.f-h {
  max-width: 21ch; margin: 0 auto;
  font-size: calc(5.6 * var(--wds-s)); font-weight: 700;
  letter-spacing: -0.035em; line-height: 1.05;
  color: var(--wds-ink);
}
.f-sub {
  max-width: 34ch; margin: calc(1.8 * var(--wds-s)) auto 0;
  font-size: calc(2 * var(--wds-s)); line-height: 1.45; color: var(--wds-ink-dim);
}
.f-cta { display: flex; gap: calc(1.6 * var(--wds-s)); justify-content: center; margin-top: calc(2.6 * var(--wds-s)); }
.f-btn {
  font-size: calc(2 * var(--wds-s)); font-weight: 600;
  padding: calc(1.5 * var(--wds-s)) calc(3.4 * var(--wds-s));
  border-radius: 99px;
  background: var(--wds-ink); color: var(--wds-surface);
}
.f-btn.ghost { background: transparent; color: var(--wds-ink); border: 1px solid var(--wds-ink); }

/* Payment rail. Deliberately unbranded — the reference carries Stripe,
   PayPal, Mastercard and Apple Pay marks, which cannot ship. Grey bars
   read as logos without borrowing anyone's trademark. */
.f-rail {
  position: absolute; z-index: 2;
  left: calc(6 * var(--wds-s)); right: calc(6 * var(--wds-s)); bottom: calc(3.4 * var(--wds-s));
  display: flex; align-items: center; justify-content: space-between; gap: calc(2 * var(--wds-s));
  padding: calc(2.2 * var(--wds-s)) calc(3.4 * var(--wds-s));
  border: 1px solid var(--wds-hair);
  border-radius: calc(2.4 * var(--wds-s));
  background: color-mix(in srgb, var(--wds-surface) 88%, transparent);
  box-shadow: 0 calc(1.4 * var(--wds-s)) calc(3.4 * var(--wds-s)) color-mix(in srgb, var(--ink) 10%, transparent);
}
.f-mark { height: calc(1.5 * var(--wds-s)); border-radius: 99px; background: var(--wds-ink-dim); opacity: 0.45; }

/* Once the mock stops growing, centre it and let the frame gain margin — the
   wide-monitor behaviour of a real site rather than a stretched one. These are
   absolutely positioned with both left and right set, so max-width plus auto
   inline margins centres them; overriding left/right to auto would drop them
   back to static flow and break the rail's bottom anchoring. */
.f-nav, .f-body, .f-rail {
  max-width: calc(104 * var(--wds-s));
  margin-inline: auto;
}

/* ===========================================================
   DEPTH — technology

   Deliberately the opposite design language to FLOW. Where Flow is
   centred, rounded, soft-weighted and pale, Depth is left-aligned,
   square-cornered, tightly tracked and technical. Same two typefaces,
   same scale system — the difference is entirely structure, alignment,
   density and colour. Proving that is the point of the section.
   =========================================================== */
.d-site { position: absolute; inset: 0; overflow: hidden; background: var(--wds-surface); }

/* Contrast scrim. A field this busy will otherwise eat the copy — the CTA row
   in particular lands on a frame edge. Angled and asymmetric so it reads as a
   lighting decision rather than a grey box behind the text, and pointer-events
   none so it never intercepts the parallax move. */
.d-site::after {
  content: '';
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  background: linear-gradient(102deg,
    color-mix(in srgb, var(--wds-surface) 90%, transparent) 2%,
    color-mix(in srgb, var(--wds-surface) 56%, transparent) 27%,
    color-mix(in srgb, var(--wds-surface) 12%, transparent) 52%,
    transparent 70%);
}
.d-canvas   { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.d-fallback { position: absolute; inset: 0; width: 100%; height: 100%; display: none; }
.wds-panel.no-gl .d-canvas   { display: none; }
.wds-panel.no-gl .d-fallback { display: block; }

.d-nav {
  position: absolute; top: 0; left: 0; right: 0; z-index: 2;
  display: flex; align-items: center; gap: calc(3 * var(--wds-s));
  padding: calc(3.4 * var(--wds-s)) calc(4.5 * var(--wds-s));
  border-bottom: 1px solid var(--wds-hair);
}
.d-brand {
  font-weight: 800; font-size: calc(2.6 * var(--wds-s));
  letter-spacing: 0.02em; text-transform: uppercase; color: var(--wds-ink);
}
.d-brand i { font-style: normal; color: var(--wds-depth); }
.d-links { display: flex; gap: calc(2.6 * var(--wds-s)); margin-left: auto; }
.d-links span {
  font-family: var(--font-mono);
  font-size: calc(1.5 * var(--wds-s)); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--wds-ink-dim);
}

/* Left-aligned, not centred — the single loudest structural difference
   from Flow, and the first thing read as "different studio". */
.d-body {
  position: absolute; z-index: 2;
  left: calc(4.5 * var(--wds-s)); top: calc(17 * var(--wds-s));
  max-width: calc(66 * var(--wds-s));
}
.d-eyebrow {
  display: flex; align-items: center; gap: calc(1.4 * var(--wds-s));
  font-family: var(--font-mono);
  font-size: calc(1.4 * var(--wds-s)); letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--wds-depth);
  margin-bottom: calc(2.4 * var(--wds-s));
}
.d-eyebrow::before {
  content: ''; width: calc(4 * var(--wds-s)); height: 1px; background: var(--wds-depth);
}
.d-h {
  font-size: calc(6.2 * var(--wds-s)); font-weight: 800;
  letter-spacing: -0.045em; line-height: 0.98; color: var(--wds-ink);
}
.d-h em { font-style: normal; color: var(--wds-depth); }
.d-sub {
  margin-top: calc(2.2 * var(--wds-s));
  max-width: calc(42 * var(--wds-s));
  font-size: calc(1.9 * var(--wds-s)); line-height: 1.5; color: var(--wds-ink-dim);
}
.d-cta { display: flex; gap: calc(1.4 * var(--wds-s)); margin-top: calc(3 * var(--wds-s)); }
/* Square, outlined — Flow's are filled pills. */
.d-btn {
  font-family: var(--font-mono);
  font-size: calc(1.5 * var(--wds-s)); letter-spacing: 0.16em; text-transform: uppercase;
  padding: calc(1.6 * var(--wds-s)) calc(3 * var(--wds-s));
  border: 1px solid var(--wds-depth); color: var(--wds-depth); background: none;
}
.d-btn.solid { background: var(--wds-depth); color: var(--wds-surface); }

/* Corner readout — depicts capability, carries no figure. Hard rule 2:
   a label with a rule mark is a graphic; a number here would be a claim. */
.d-meta {
  position: absolute; z-index: 2;
  right: calc(4.5 * var(--wds-s)); bottom: calc(4 * var(--wds-s));
  display: flex; flex-direction: column; gap: calc(1.2 * var(--wds-s));
  text-align: right;
}
.d-meta span {
  font-family: var(--font-mono);
  font-size: calc(1.3 * var(--wds-s)); letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--wds-ink-dim);
}
.d-meta i {
  display: block; height: 1px; width: calc(10 * var(--wds-s));
  margin-left: auto; background: var(--wds-hair);
}

/* ===========================================================
   SPEED — automotive

   Third distinct language: heavy condensed uppercase, hard clipped
   edges, red accent, image-led. Flow is centred and soft, Depth is
   left-aligned and technical, Speed is loud.

   The hero photograph is generated art of a FICTIONAL vehicle —
   deliberately unbranded, with no badge, decal or lettering anywhere,
   and no people in frame. The reference for this tab carries Audi
   livery and a photo of a person in its consultation card; neither
   can ship.
   =========================================================== */
.s-site { position: absolute; inset: 0; overflow: hidden; background: var(--wds-surface); }

.s-photo {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  /* Scale tracks the throttle. transform only — never width/height — so this
     stays on the compositor and never triggers layout. */
  transform: scale(calc(1.04 + 0.09 * var(--s-thr, 0)));
  transform-origin: 58% 62%;
  will-change: transform;
}
.s-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 1; }

/* Vignette + left scrim: the photograph is busiest exactly where the
   headline sits. */
.s-site::after {
  content: '';
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(95deg,
      color-mix(in srgb, var(--wds-surface) 88%, transparent) 0%,
      color-mix(in srgb, var(--wds-surface) 40%, transparent) 38%,
      transparent 66%),
    radial-gradient(120% 90% at 50% 50%,
      transparent 42%,
      color-mix(in srgb, var(--wds-surface) 70%, transparent) 100%);
}

.s-nav {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3;
  display: flex; align-items: center; gap: calc(3 * var(--wds-s));
  padding: calc(3.2 * var(--wds-s)) calc(4.2 * var(--wds-s));
}
.s-brand {
  font-weight: 900; font-size: calc(2.7 * var(--wds-s));
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--wds-ink);
}
.s-links { display: flex; gap: calc(2.6 * var(--wds-s)); margin-left: auto; }
.s-links span {
  font-family: var(--font-mono); font-size: calc(1.4 * var(--wds-s));
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--wds-ink-dim);
}

.s-body {
  position: absolute; z-index: 3;
  left: calc(4.2 * var(--wds-s)); top: calc(15 * var(--wds-s));
  max-width: calc(60 * var(--wds-s));
}
.s-h {
  font-size: calc(8.4 * var(--wds-s)); font-weight: 900;
  line-height: 0.88; letter-spacing: -0.03em;
  text-transform: uppercase; color: var(--wds-ink);
}
.s-h em { font-style: normal; color: var(--wds-speed); }
.s-sub {
  margin-top: calc(2.2 * var(--wds-s)); max-width: calc(38 * var(--wds-s));
  font-size: calc(1.8 * var(--wds-s)); line-height: 1.5; color: var(--wds-ink-dim);
}
/* Clipped corner rather than a radius — the angular counterpart to Flow's
   pills and Depth's squares. */
.s-btn {
  display: inline-block; margin-top: calc(2.8 * var(--wds-s));
  font-family: var(--font-mono); font-weight: 700;
  font-size: calc(1.5 * var(--wds-s)); letter-spacing: 0.18em; text-transform: uppercase;
  padding: calc(1.7 * var(--wds-s)) calc(3.4 * var(--wds-s));
  background: var(--wds-speed); color: var(--wds-ink);
  clip-path: polygon(0 0, 100% 0, calc(100% - 1.6 * var(--wds-s)) 100%, 0 100%);
}

/* Controls: a real range input and a real toggle button, so both are
   keyboard-operable without any extra code. */
.s-ctl {
  position: absolute; z-index: 3;
  right: calc(4.2 * var(--wds-s)); bottom: calc(4 * var(--wds-s));
  display: flex; align-items: center; gap: calc(2.2 * var(--wds-s));
}
.s-thr { display: flex; align-items: center; gap: calc(1.4 * var(--wds-s)); }
.s-thr label {
  font-family: var(--font-mono); font-size: calc(1.2 * var(--wds-s));
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--wds-ink-dim);
}
.s-range {
  -webkit-appearance: none; appearance: none;
  width: calc(26 * var(--wds-s)); height: calc(0.5 * var(--wds-s));
  background: color-mix(in srgb, var(--wds-ink) 28%, transparent);
  outline: none; cursor: pointer;
}
.s-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: calc(1.6 * var(--wds-s)); height: calc(3.2 * var(--wds-s));
  background: var(--wds-speed); cursor: pointer; border: 0; border-radius: 0;
}
.s-range::-moz-range-thumb {
  width: calc(1.6 * var(--wds-s)); height: calc(3.2 * var(--wds-s));
  background: var(--wds-speed); cursor: pointer; border: 0; border-radius: 0;
}
.s-range:focus-visible { outline: 2px solid var(--orange); outline-offset: 4px; }

.s-audio {
  display: inline-flex; align-items: center; gap: calc(1 * var(--wds-s));
  font-family: var(--font-mono); font-size: calc(1.2 * var(--wds-s));
  letter-spacing: 0.18em; text-transform: uppercase;
  padding: calc(1.1 * var(--wds-s)) calc(2 * var(--wds-s));
  color: var(--wds-ink-dim); background: none;
  border: 1px solid color-mix(in srgb, var(--wds-ink) 30%, transparent);
  cursor: pointer;
}
.s-audio:hover { color: var(--wds-ink); border-color: var(--wds-ink); }
.s-audio[aria-pressed="true"] { color: var(--wds-speed); border-color: var(--wds-speed); }
.s-audio:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.s-audio svg { width: calc(1.5 * var(--wds-s)); height: calc(1.5 * var(--wds-s)); flex: 0 0 auto; }

/* Unlabelled arc. Hard rule 2: a gauge with a number on it is a claim about
   something that does not exist; a gauge without one is a graphic. */
.s-gauge { position: absolute; z-index: 3; right: calc(4.2 * var(--wds-s)); top: calc(13 * var(--wds-s)); width: calc(16 * var(--wds-s)); }
.s-gauge svg { width: 100%; height: auto; display: block; }
.s-gauge .trk { stroke: color-mix(in srgb, var(--wds-ink) 22%, transparent); }
.s-gauge .val { stroke: var(--wds-speed); transition: stroke-dashoffset 0.12s linear; }

@media (prefers-reduced-motion: reduce) {
  /* Static, mid-throttle composition; the loop never starts and the audio
     toggle is hidden entirely (see the JS). */
  .s-photo { transform: scale(1.06); }
  .s-gauge .val { transition: none; }
}

/* ===========================================================
   RETAIL — e-commerce

   Fourth language: fashion editorial. An oversized wordmark bleeding
   off the frame in mix-blend-mode over full-bleed product photography,
   sparse mono captions parked in the corners, and a lot of air.
   Flow is centred and soft, Depth technical, Speed loud — this one is
   quiet and confident, and lets the photograph carry it.

   NO PRICES ANYWHERE. Hard rule 2: an invented price is invented
   business data. The cart badge is the one number on the panel and it
   is user-caused — it counts what the visitor just clicked.
   =========================================================== */
.r-site { position: absolute; inset: 0; overflow: hidden; background: var(--wds-surface); }
.r-photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 52% 38%; display: block;
  transform: scale(1.02);
  transition: transform 0.9s var(--ease-out);
}
.r-site:hover .r-photo { transform: scale(1.06); }
.r-site::after {
  content: '';
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--wds-surface) 55%, transparent) 0%,
    transparent 26%,
    transparent 58%,
    color-mix(in srgb, var(--wds-surface) 72%, transparent) 100%);
}

.r-top {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3;
  display: flex; gap: calc(4 * var(--wds-s));
  padding: calc(3 * var(--wds-s)) calc(3.6 * var(--wds-s));
  font-family: var(--font-mono);
  font-size: calc(1.35 * var(--wds-s)); line-height: 1.7;
  letter-spacing: 0.1em; color: var(--wds-ink);
}
.r-top div span { display: block; }
.r-cart {
  margin-left: auto; display: inline-flex; align-items: center; gap: calc(0.9 * var(--wds-s));
  font-family: var(--font-mono); font-size: calc(1.35 * var(--wds-s));
  letter-spacing: 0.1em; color: var(--wds-ink);
  background: none; border: 0; padding: 0; cursor: default;
}
.r-cart b {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: calc(2.6 * var(--wds-s)); height: calc(2.6 * var(--wds-s));
  padding: 0 calc(0.6 * var(--wds-s));
  border-radius: 99px; font-weight: 700;
  background: var(--wds-retail); color: var(--wds-surface);
  transform: scale(0);
  transition: transform 0.28s var(--ease-out);
}
.r-cart.has b { transform: scale(1); }

/* The wordmark deliberately runs off the left edge and sits in
   difference blend, so it reads as printed onto the image rather than
   placed on top of it. */
.r-mark {
  position: absolute; z-index: 3;
  left: calc(-1.5 * var(--wds-s)); bottom: calc(11 * var(--wds-s));
  font-size: calc(16 * var(--wds-s)); font-weight: 800;
  letter-spacing: -0.055em; line-height: 0.8;
  color: var(--wds-ink);
  mix-blend-mode: difference;
  pointer-events: none;
}
.r-mark sup { font-size: 0.3em; vertical-align: super; letter-spacing: 0; }

.r-copy {
  position: absolute; z-index: 3;
  right: calc(3.6 * var(--wds-s)); bottom: calc(11 * var(--wds-s));
  max-width: calc(28 * var(--wds-s)); text-align: right;
  font-size: calc(1.6 * var(--wds-s)); line-height: 1.55; color: var(--wds-ink);
}
.r-foot {
  position: absolute; z-index: 3;
  left: calc(3.6 * var(--wds-s)); right: calc(3.6 * var(--wds-s)); bottom: calc(3.4 * var(--wds-s));
  display: flex; align-items: center; gap: calc(2 * var(--wds-s));
  font-family: var(--font-mono); font-size: calc(1.3 * var(--wds-s));
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--wds-ink-dim);
}
.r-add {
  margin-left: auto;
  font-family: var(--font-mono); font-weight: 700;
  font-size: calc(1.4 * var(--wds-s)); letter-spacing: 0.18em; text-transform: uppercase;
  padding: calc(1.5 * var(--wds-s)) calc(3.2 * var(--wds-s));
  background: var(--wds-ink); color: var(--wds-surface);
  border: 0; cursor: pointer;
  transition: background 0.2s var(--ease-out), color 0.2s var(--ease-out);
}
.r-add:hover { background: var(--wds-retail); color: var(--wds-surface); }
.r-add:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
.r-add.is-done { background: var(--wds-retail); color: var(--wds-surface); }

/* Fly-to-cart dot. One element, transform only, removed on animationend. */
.r-fly {
  position: absolute; z-index: 4; pointer-events: none;
  width: calc(1.6 * var(--wds-s)); height: calc(1.6 * var(--wds-s));
  border-radius: 50%; background: var(--wds-retail);
}

@media (prefers-reduced-motion: reduce) {
  .r-photo, .r-site:hover .r-photo { transform: scale(1.03); transition: none; }
  .r-cart b { transition: none; }
  .r-fly { display: none; }
}

/* ===========================================================
   SPACE — real estate

   Fifth language: architectural. Hairline rules, wide tracking, a lot
   of air, and a slim instrument bar along the bottom. Where Retail
   shouts with a 16-unit wordmark, this one whispers.

   The tour is a horizontal strip of rooms moved with a single
   translateX, plus a floor plan whose marker tracks the current room.
   One transform on one element — compositor-only, and no animation
   loop anywhere, so this tab costs nothing at rest. There is no
   auto-tour on purpose: the pitch is that the VISITOR walks the
   property, and an auto-advance would be motion noise plus a second
   timer to tear down.
   =========================================================== */
.p-site { position: absolute; inset: 0; overflow: hidden; background: var(--wds-surface); }

.p-strip {
  position: absolute; inset: 0;
  display: flex; width: 400%;              /* 4 rooms */
  transform: translateX(calc(var(--p-room, 0) * -25%));
  transition: transform 0.72s var(--ease-out);
}
.p-room { position: relative; width: 25%; height: 100%; flex: 0 0 25%; }
.p-room img { width: 100%; height: 100%; object-fit: cover; display: block; }
.p-site::after {
  content: '';
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  /* Reaches to ~44% because the title sits at 14 units on a 71-unit stage and
     these interiors are bright exactly where it lands — daylight through a
     full-height window directly behind the headline. */
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--wds-surface) 68%, transparent) 0%,
    color-mix(in srgb, var(--wds-surface) 42%, transparent) 24%,
    color-mix(in srgb, var(--wds-surface) 12%, transparent) 40%,
    transparent 54%,
    transparent 58%,
    color-mix(in srgb, var(--wds-surface) 84%, transparent) 100%);
}

.p-nav {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3;
  display: flex; align-items: center; gap: calc(3 * var(--wds-s));
  padding: calc(3.2 * var(--wds-s)) calc(4 * var(--wds-s));
}
.p-brand {
  font-weight: 500; font-size: calc(2.6 * var(--wds-s));
  letter-spacing: 0.34em; text-transform: uppercase; color: var(--wds-ink);
}
.p-links { display: flex; gap: calc(2.8 * var(--wds-s)); margin-left: auto; }
.p-links span {
  font-size: calc(1.5 * var(--wds-s)); letter-spacing: 0.06em; color: var(--wds-ink-dim);
}

.p-title {
  position: absolute; z-index: 3;
  left: calc(4 * var(--wds-s)); top: calc(14 * var(--wds-s));
  max-width: calc(46 * var(--wds-s));
}
.p-eyebrow {
  font-family: var(--font-mono); font-size: calc(1.3 * var(--wds-s));
  letter-spacing: 0.28em; text-transform: uppercase; color: var(--wds-ink-dim);
  margin-bottom: calc(1.8 * var(--wds-s));
}
.p-h {
  font-size: calc(5.4 * var(--wds-s)); font-weight: 400;
  letter-spacing: -0.02em; line-height: 1.08; color: var(--wds-ink);
}

/* Instrument bar. Plan on the left, room index on the right. */
.p-bar {
  position: absolute; z-index: 3;
  left: calc(4 * var(--wds-s)); right: calc(4 * var(--wds-s)); bottom: calc(3.4 * var(--wds-s));
  display: flex; align-items: flex-end; gap: calc(3 * var(--wds-s));
  padding-top: calc(2 * var(--wds-s));
  border-top: 1px solid color-mix(in srgb, var(--wds-ink) 26%, transparent);
}
.p-plan { width: calc(26 * var(--wds-s)); flex: 0 0 auto; }
.p-plan svg { width: 100%; height: auto; display: block; }
.p-plan .rm {
  fill: color-mix(in srgb, var(--wds-ink) 8%, transparent);
  stroke: color-mix(in srgb, var(--wds-ink) 34%, transparent);
  stroke-width: 1.1;
  cursor: pointer;
  transition: fill 0.25s var(--ease-out);
}
.p-plan .rm:hover { fill: color-mix(in srgb, var(--wds-ink) 18%, transparent); }
.p-plan .rm.is-on { fill: color-mix(in srgb, var(--wds-space) 46%, transparent); }
.p-plan .mk {
  fill: var(--wds-space);
  transition: transform 0.72s var(--ease-out);
}
.p-plan .rm:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }

.p-rooms { margin-left: auto; display: flex; gap: calc(2.4 * var(--wds-s)); }
.p-rooms button {
  position: relative;
  font-family: var(--font-mono); font-size: calc(1.35 * var(--wds-s));
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--wds-ink-dim); background: none; border: 0; padding: calc(0.6 * var(--wds-s)) 0;
  cursor: pointer;
  transition: color 0.25s var(--ease-out);
}
.p-rooms button:hover { color: var(--wds-ink); }
.p-rooms button[aria-current="true"] { color: var(--wds-ink); }
.p-rooms button[aria-current="true"]::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: calc(-2.1 * var(--wds-s));
  height: 2px; background: var(--wds-space);
}
.p-rooms button:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .p-strip, .p-plan .mk { transition: none; }
}

/* ===========================================================
   SYSTEM — product dashboard

   The sixth language, and the only one that is an APPLICATION rather
   than a marketing page. Everything else in the set sells; this one
   works. That is the range statement: the same studio ships the
   landing page and the product behind it.

   It is also the only LIGHT demo, deliberately. Five near-black
   panels in a row begin to read as one house style, which is the
   opposite of what the section is arguing.

   An earlier pass built this as a sparse corporate marketing page:
   six capability labels, no figures. It was calm, legible, and told a
   visitor nothing. A dashboard with no numbers in it is not a
   dashboard, it is a wireframe.

   ON HARD RULE 2. The rule bans invented dashboard figures because
   fabricated numbers on A1's own pages imply A1 produced those
   results. These are a FICTIONAL product's demo values, inside a
   labelled browser frame, on a page whose entire subject is design
   work. Same reasoning as the fictional brand names and example.com
   URLs elsewhere in the set. No figure here appears outside the
   frame, and none is presented as an A1 outcome.
   =========================================================== */
.y-site {
  position: absolute; inset: 0; overflow: hidden;
  background: var(--wds-sys-bg);
  color: var(--wds-sys-ink);
  display: flex;
}

/* Icon rail */
.y-side {
  flex: 0 0 auto;
  width: calc(8 * var(--wds-s));
  background: var(--wds-sys-card);
  border-right: 1px solid var(--wds-sys-line);
  display: flex; flex-direction: column; align-items: center;
  padding: calc(2.4 * var(--wds-s)) 0;
  gap: calc(2 * var(--wds-s));
}
.y-side i {
  display: block; width: calc(3.2 * var(--wds-s)); height: calc(3.2 * var(--wds-s));
  border-radius: calc(1 * var(--wds-s));
  background: var(--wds-sys-line);
}
.y-side i.on { background: var(--wds-sys-lime); }
.y-side i.av { border-radius: 50%; background: var(--wds-sys-a); margin-top: auto; }

.y-main {
  flex: 1 1 auto; min-width: 0;
  padding: calc(2.4 * var(--wds-s));
  display: flex; flex-direction: column; gap: calc(1.7 * var(--wds-s));
}

/* Top bar */
.y-top { display: flex; align-items: center; gap: calc(1.6 * var(--wds-s)); }
.y-hi { font-size: calc(2.9 * var(--wds-s)); font-weight: 800; letter-spacing: -0.03em; line-height: 1.1; }
.y-hi small {
  display: block; font-size: calc(1.35 * var(--wds-s)); font-weight: 400;
  color: var(--wds-sys-dim); letter-spacing: 0; margin-top: calc(0.5 * var(--wds-s));
}
.y-search {
  margin-left: auto;
  display: flex; align-items: center; gap: calc(1.1 * var(--wds-s));
  width: calc(28 * var(--wds-s)); max-width: 40%;
  padding: calc(1.2 * var(--wds-s)) calc(1.8 * var(--wds-s));
  background: var(--wds-sys-card); border: 1px solid var(--wds-sys-line);
  border-radius: 99px;
  font-size: calc(1.4 * var(--wds-s)); color: var(--wds-sys-dim);
  white-space: nowrap; overflow: hidden;
}
.y-search span {
  width: calc(1.5 * var(--wds-s)); height: calc(1.5 * var(--wds-s));
  border: 1.5px solid currentColor; border-radius: 50%; flex: 0 0 auto;
}
.y-up {
  display: inline-flex; align-items: center; gap: calc(0.9 * var(--wds-s));
  padding: calc(1.3 * var(--wds-s)) calc(2.4 * var(--wds-s));
  border-radius: 99px; background: var(--wds-sys-deep); color: var(--wds-sys-card);
  font-size: calc(1.4 * var(--wds-s)); font-weight: 600; white-space: nowrap;
}
.y-up b { color: var(--wds-sys-lime); font-weight: 700; }

/* Card grid */
.y-row { display: grid; gap: calc(1.7 * var(--wds-s)); }
.y-row.a { grid-template-columns: 1.8fr 1fr; }
.y-row.b { grid-template-columns: 1fr 1.2fr 1fr; flex: 1 1 auto; min-height: 0; }
.y-card {
  background: var(--wds-sys-card);
  border-radius: calc(2.2 * var(--wds-s));
  padding: calc(2 * var(--wds-s));
  min-width: 0; overflow: hidden; position: relative;
  display: flex; flex-direction: column;
}

/* Promo */
.y-promo { background: var(--wds-sys-blue); color: var(--wds-sys-card); padding: 0; flex-direction: row; }
.y-promo-t { flex: 1 1 auto; padding: calc(2.2 * var(--wds-s)); display: flex; flex-direction: column; min-width: 0; }
.y-promo h4 {
  font-size: calc(3.2 * var(--wds-s)); font-weight: 800; line-height: 1.05;
  letter-spacing: -0.035em; color: var(--wds-sys-card); max-width: 13ch;
}
.y-promo p { font-size: calc(1.35 * var(--wds-s)); opacity: 0.86; margin-top: calc(1 * var(--wds-s)); max-width: 26ch; line-height: 1.45; }
.y-promo-cta {
  margin-top: auto; align-self: flex-start;
  display: inline-flex; align-items: center; gap: calc(1.1 * var(--wds-s));
  padding: calc(1.3 * var(--wds-s)) calc(2.4 * var(--wds-s));
  background: var(--wds-sys-deep); color: var(--wds-sys-card);
  border-radius: 99px; font-size: calc(1.4 * var(--wds-s)); font-weight: 600;
}
.y-promo-img { flex: 0 0 40%; position: relative; }
.y-promo-img img { width: 100%; height: 100%; object-fit: cover; object-position: 44% 38%; display: block; }
.y-faces { display: flex; align-items: center; gap: calc(1.4 * var(--wds-s)); margin-top: calc(1.6 * var(--wds-s)); font-size: calc(1.25 * var(--wds-s)); }
.y-faces em { font-style: normal; display: flex; }
.y-faces u {
  display: inline-block; width: calc(2.4 * var(--wds-s)); height: calc(2.4 * var(--wds-s));
  border-radius: 50%; border: 2px solid var(--wds-sys-blue); margin-right: calc(-0.9 * var(--wds-s));
  background: var(--wds-sys-card);
}

/* Utilisation — the reference's glass row generalised to a unit grid */
.y-util { background: var(--wds-sys-deep); color: var(--wds-sys-card); }
.y-util h5 { font-size: calc(1.8 * var(--wds-s)); font-weight: 700; color: var(--wds-sys-card); }
.y-util p { font-size: calc(1.2 * var(--wds-s)); opacity: 0.6; margin-top: calc(0.6 * var(--wds-s)); line-height: 1.45; }
.y-units { display: grid; grid-template-columns: repeat(8, 1fr); gap: calc(0.5 * var(--wds-s)); margin-top: calc(1.5 * var(--wds-s)); }
.y-units b { display: block; height: calc(2.4 * var(--wds-s)); border-radius: calc(0.4 * var(--wds-s)); background: color-mix(in srgb, var(--wds-sys-card) 20%, transparent); }
.y-units b.f { background: var(--wds-sys-card); }
.y-util-n { display: flex; align-items: baseline; justify-content: flex-end; gap: calc(0.6 * var(--wds-s)); margin-top: auto; padding-top: calc(1.2 * var(--wds-s)); }
.y-util-n strong { font-size: calc(4.4 * var(--wds-s)); font-weight: 800; letter-spacing: -0.045em; line-height: 1; }
.y-util-n span { font-size: calc(1.25 * var(--wds-s)); opacity: 0.6; }

/* Metric cards */
.y-head { display: flex; align-items: center; gap: calc(1.1 * var(--wds-s)); }
.y-head i { width: calc(2.6 * var(--wds-s)); height: calc(2.6 * var(--wds-s)); border-radius: calc(0.8 * var(--wds-s)); background: var(--m, var(--wds-sys-c)); flex: 0 0 auto; }
.y-head h5 { font-size: calc(2 * var(--wds-s)); font-weight: 700; letter-spacing: -0.02em; }
.y-head em { margin-left: auto; font-style: normal; font-size: calc(2 * var(--wds-s)); font-weight: 700; white-space: nowrap; }
.y-head em u { text-decoration: none; font-size: calc(1.15 * var(--wds-s)); color: var(--wds-sys-dim); font-weight: 500; }
.y-sub2 { display: flex; justify-content: space-between; gap: calc(1 * var(--wds-s)); margin-top: calc(1.1 * var(--wds-s)); font-size: calc(1.15 * var(--wds-s)); color: var(--wds-sys-dim); }
.y-big { font-size: calc(4.8 * var(--wds-s)); font-weight: 800; letter-spacing: -0.045em; line-height: 1; margin-top: calc(1.2 * var(--wds-s)); }
.y-big u { text-decoration: none; font-size: calc(1.5 * var(--wds-s)); color: var(--wds-sys-dim); font-weight: 500; }

.y-bars { display: flex; align-items: flex-end; gap: calc(0.3 * var(--wds-s)); height: calc(8 * var(--wds-s)); margin-top: calc(1.4 * var(--wds-s)); }
.y-bars i { flex: 1 1 0; border-radius: calc(0.3 * var(--wds-s)); background: var(--wds-sys-lime); min-width: 0; }
.y-scale { display: flex; justify-content: space-between; font-size: calc(1.05 * var(--wds-s)); color: var(--wds-sys-dim); margin-top: calc(0.7 * var(--wds-s)); }
.y-legs { display: flex; gap: calc(1.8 * var(--wds-s)); margin-top: auto; padding-top: calc(1.4 * var(--wds-s)); border-top: 1px solid var(--wds-sys-line); }
.y-legs div { font-size: calc(1.8 * var(--wds-s)); font-weight: 700; }
.y-legs div u {
  display: block; text-decoration: none; font-size: calc(1.05 * var(--wds-s));
  color: var(--wds-sys-dim); font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; margin-top: calc(0.2 * var(--wds-s));
}

.y-wave { margin-top: calc(1.2 * var(--wds-s)); }
.y-wave svg { width: 100%; height: auto; display: block; }
.y-wave path { fill: none; stroke: var(--wds-sys-c); stroke-width: 2.4; stroke-linecap: round; }
.y-foot2 { display: flex; align-items: flex-end; justify-content: space-between; gap: calc(1 * var(--wds-s)); margin-top: auto; }
.y-foot2 p { font-size: calc(1.1 * var(--wds-s)); color: var(--wds-sys-dim); text-align: right; line-height: 1.5; }
.y-foot2 p b { display: block; color: var(--wds-sys-ink); }

.y-note {
  margin-top: calc(1.3 * var(--wds-s));
  padding: calc(1.5 * var(--wds-s));
  background: var(--wds-sys-bg); border-radius: calc(1.3 * var(--wds-s));
  font-size: calc(1.2 * var(--wds-s)); color: var(--wds-sys-dim); line-height: 1.5;
}
.y-note b { display: inline-block; color: var(--wds-sys-ink); margin-bottom: calc(0.5 * var(--wds-s)); }
.y-pager { display: flex; align-items: center; gap: calc(0.7 * var(--wds-s)); margin-top: auto; padding-top: calc(1.3 * var(--wds-s)); font-size: calc(1.25 * var(--wds-s)); color: var(--wds-sys-dim); }
.y-pager s { text-decoration: none; width: calc(2.6 * var(--wds-s)); height: calc(2.6 * var(--wds-s)); border: 1px solid var(--wds-sys-line); border-radius: 50%; }
.y-pager s.l { margin-left: auto; }

/* -----------------------------------------------------------
   Reduced motion — hard rule 5.
   The globe's own loop is stopped in JS (it draws exactly one frame
   and schedules nothing), so there is nothing to disable here beyond
   the chrome transitions.
   ----------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .wds-tab,
  .wds-stage { transition: none; }
}

/* -----------------------------------------------------------
   Narrow
   ----------------------------------------------------------- */
@media (max-width: 1100px) {
  .wds-tab { font-size: 10px; letter-spacing: 0.06em; padding: 10px 2px 9px; }
}
@media (max-width: 480px) {
  .wds-tab { font-size: 9px; letter-spacing: 0.04em; padding: 9px 1px 8px; }
  .wds-url { font-size: 9px; }
}
