/* ============================================================
   Yahia Elghayesh: portfolio
   "Spark to product": raw making, the engineer, the finished things.
   Black and Tan: true off-black ground, one warm tan accent, sharp
   contrast. Geist for everything read, Geist Mono for every label
   and number. See DESIGN.md.
   ============================================================ */
@font-face {
  font-family: "Geist";
  src: url("assets/fonts/Geist-Variable.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("assets/fonts/GeistMono-Variable.woff2") format("woff2");
  font-weight: 100 900; font-style: normal; font-display: swap;
}

:root {
  --bg: #12100d;
  --bg-deep: #0b0a08;
  --bg-card: #1d1a15;
  --ink: #f2ede6;
  --ink-2: #b8afa3;
  --ink-3: #8a8175;
  --line: #2c2822;
  --line-strong: #3d372f;
  --accent: #cf9d5c;
  --accent-deep: #e8c088;
  --accent-soft: #3a2f1f;

  --font: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --fs-mega: clamp(4.5rem, 1rem + 15.5vw, 17rem);
  --fs-display: clamp(3rem, 1.6rem + 6vw, 7.5rem);
  --fs-h1: clamp(2.4rem, 1.4rem + 3.6vw, 4.6rem);
  --fs-h2: clamp(1.9rem, 1.2rem + 2.4vw, 3.4rem);
  --fs-h3: 1.2rem;
  --fs-body: 1.0625rem;
  --fs-small: 0.9rem;
  --fs-label: 0.78rem;

  /* Light and shadow for photos with no background: drop-shadows follow the
     photo's own outline, never its box. A thin warm rim on the edges facing
     up (the key light), a tight contact shadow and a soft one under it. */
  --cut-light: drop-shadow(0 -1px 0 rgba(255, 232, 200, 0.22));
  --cut-shadow: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.42)) drop-shadow(0 12px 16px rgba(0, 0, 0, 0.36));
  --cut-shadow-lifted: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.4)) drop-shadow(0 22px 22px rgba(0, 0, 0, 0.42));
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1.25rem;
  --space-5: 2rem;
  --space-6: 3rem;
  --space-7: 5rem;
  --space-8: 9rem;

  /* One radius scale: cards and photos 14px, every interactive pill fully round. */
  --radius: 14px;
  --radius-sm: 8px;
  --measure: 62ch;
  --page-pad: clamp(1.25rem, 5vw, 4rem);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 0.25s;

  /* Layers, low to high. */
  --z-bg: 0;
  --z-main: 1;
  --z-gl: 50;
  --z-top: 100;
  --z-modal: 200;
  --z-intro: 300;
}

/* ============================================================
   Base
   ============================================================ */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; overflow-x: clip; scrollbar-gutter: stable; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "ss01", "cv11";
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; padding: 0; }
ul, ol { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, p, figure { margin: 0; }
strong { font-weight: 600; color: var(--ink); }
em { font-style: italic; }

::selection { background: var(--accent); color: var(--bg-deep); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.skip-link {
  position: fixed; left: var(--space-4); top: -3rem;
  background: var(--ink); color: var(--bg);
  padding: var(--space-2) var(--space-4); border-radius: 999px;
  z-index: calc(var(--z-intro) + 1); transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--space-4); }

.container { max-width: 88rem; margin-inline: auto; padding-inline: var(--page-pad); }
/* Space between sections scales with the screen height, so short laptop
   screens do not scroll through long empty bands. */
.section { padding-block: clamp(3.5rem, 9vh, 6rem); position: relative; }
.section-head { margin-bottom: var(--space-6); max-width: 44rem; }
.section-head p { margin-top: var(--space-4); color: var(--ink-2); font-size: 1.1rem; }
.section-title {
  font-size: var(--fs-h1); font-weight: 600; letter-spacing: -0.035em; line-height: 1.02;
  padding-bottom: 0.1em;
}

/* Heading words hinge up out of a slot (motion.js). The hidden state is only
   applied when motion.js has added .split, i.e. when something will reveal it. */
.split { overflow: hidden; padding-bottom: 0.12em; margin-bottom: -0.12em; }
.split .line { display: inline-block; transform: translateY(110%); will-change: transform; }

/* ============================================================
   Background light and effect canvases
   ============================================================ */
/* Two still pools of warm light behind the page. Static: they are painted
   once and never repainted while scrolling. */
.depth-bg { position: fixed; inset: 0; z-index: var(--z-bg); pointer-events: none; overflow: hidden; }
.depth-bg span { position: absolute; display: block; border-radius: 50%; }
.depth-bg .d1 {
  width: 78vmax; height: 78vmax; top: -22vmax; left: -14vmax;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 11%, transparent), transparent 62%);
}
.depth-bg .d2 {
  width: 62vmax; height: 62vmax; bottom: -20vmax; right: -12vmax;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent-deep) 7%, transparent), transparent 62%);
}
#main, .site-footer { position: relative; z-index: var(--z-main); }

/* The two WebGL effects each live inside their own section (stage.js), so
   they scroll with the page natively. Never take a click. */
.fx-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; z-index: 1; }
.fx-dissolve { opacity: 0; }


/* ============================================================
   Loading screen (every visit, index only)
   ============================================================ */
.intro-curtain { display: none; }
html.intro .intro-curtain {
  display: flex; position: fixed; inset: 0; z-index: var(--z-intro);
  background: var(--bg-deep); align-items: flex-end;
  /* Safety net: if the script that lifts it never runs, it lifts itself. */
  animation: curtain-safety 0.6s ease 9s forwards;
}
/* the page cannot scroll under it (html's own overflow, since html clips
   sideways and so keeps body's from reaching the viewport) */
html.intro { overflow: hidden; animation: intro-unlock 0.01s linear 9s forwards; }
.intro-inner {
  width: 100%; display: flex; justify-content: space-between; align-items: flex-end;
  padding: var(--page-pad);
}
.intro-count {
  font-family: var(--mono); font-size: clamp(4rem, 2rem + 12vw, 13rem); font-weight: 300;
  line-height: 0.8; letter-spacing: -0.06em; color: var(--ink); font-variant-numeric: tabular-nums;
}
.intro-name { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent-deep); }
@keyframes curtain-safety { to { transform: translateY(-100%); visibility: hidden; } }
@keyframes intro-unlock { to { overflow-x: clip; overflow-y: visible; } }

/* ============================================================
   Top bar
   ============================================================ */
/* A floating glass capsule, inset from the screen's edges. It tucks away
   while the page scrolls down and comes back the moment it scrolls up
   (common.js), so it never sits on the content being read. */
.topbar {
  position: fixed; z-index: var(--z-top); left: 0; right: 0; top: clamp(0.5rem, 1.4vh, 1rem);
  padding-inline: var(--page-pad); pointer-events: none;
  transition: transform 0.45s var(--ease), opacity 0.45s var(--ease);
}
.topbar.is-tucked { transform: translateY(calc(-100% - 1.5rem)); opacity: 0; }
.topbar-inner {
  position: relative; pointer-events: auto;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  max-width: 150rem; margin-inline: auto; min-height: 3.25rem;
  padding: 0.4rem 0.45rem 0.4rem 0.5rem; border-radius: 999px; color: var(--ink);
  background: color-mix(in srgb, #14110e 62%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(140%); backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  box-shadow: 0 14px 36px -18px rgba(0, 0, 0, 0.75), inset 0 1px 0 color-mix(in srgb, var(--ink) 7%, transparent);
}
.topbar-id { display: inline-flex; align-items: center; gap: 0.7rem; font-weight: 600; font-size: 0.98rem; letter-spacing: -0.02em; padding-right: 0.4rem; }
.topbar-id::before {
  content: "YE"; display: grid; place-items: center; width: 2.35rem; height: 2.35rem; border-radius: 50%;
  font-family: var(--mono); font-size: 0.7rem; font-weight: 600; letter-spacing: 0.06em; color: var(--accent-deep);
  background: color-mix(in srgb, var(--accent) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
}
.topbar-nav { display: flex; gap: 0.25rem; align-items: center; }
.topbar-nav a {
  position: relative; padding: 0.6rem 1.1rem; border-radius: 999px; font-size: 0.92rem; color: var(--ink-2);
  transition: color var(--dur) ease, background var(--dur) ease;
}
.topbar-nav a:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 7%, transparent); }
.topbar-nav a[aria-current="page"] { color: var(--ink); background: color-mix(in srgb, var(--ink) 10%, transparent); }
.topbar-menu-btn { display: none; }
@media (max-width: 640px) {
  .topbar-nav {
    position: absolute; top: calc(100% + 0.6rem); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0.15rem; padding: 0.6rem;
    border-radius: 1.25rem; background: color-mix(in srgb, #14110e 88%, transparent);
    -webkit-backdrop-filter: blur(16px) saturate(140%); backdrop-filter: blur(16px) saturate(140%);
    border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent); box-shadow: 0 24px 50px -20px rgba(0,0,0,0.8);
    transform: translateY(-8px) scale(0.98); transform-origin: top center; opacity: 0; pointer-events: none;
    transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
  }
  .topbar-nav.is-open { transform: none; opacity: 1; pointer-events: auto; }
  .topbar-nav a { padding: 0.95rem 1.1rem; font-size: 1.1rem; color: var(--ink); border-radius: 0.85rem; }
  .topbar-menu-btn {
    display: flex; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; border-radius: 50%;
    color: var(--ink); background: color-mix(in srgb, var(--ink) 8%, transparent);
  }
  .topbar-menu-btn .bars { width: 16px; height: 10px; position: relative; }
  .topbar-menu-btn .bars span { position: absolute; left: 0; width: 100%; height: 1.5px; border-radius: 1px; background: currentColor; transition: transform var(--dur) ease, opacity var(--dur) ease; }
  .topbar-menu-btn .bars span:nth-child(1) { top: 0; }
  .topbar-menu-btn .bars span:nth-child(2) { top: 50%; margin-top: -0.75px; }
  .topbar-menu-btn .bars span:nth-child(3) { bottom: 0; }
  .topbar-menu-btn[aria-expanded="true"] .bars span:nth-child(1) { transform: translateY(4.25px) rotate(45deg); }
  .topbar-menu-btn[aria-expanded="true"] .bars span:nth-child(2) { opacity: 0; }
  .topbar-menu-btn[aria-expanded="true"] .bars span:nth-child(3) { transform: translateY(-4.25px) rotate(-45deg); }
}
/* very short landscape screens: a slimmer capsule */
@media (max-height: 540px) and (orientation: landscape) {
  .topbar { top: 0.4rem; }
  .topbar-inner { min-height: 2.75rem; padding-block: 0.25rem; }
  .topbar-id::before { width: 2rem; height: 2rem; }
}

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2); white-space: nowrap;
  border: 1px solid color-mix(in srgb, var(--ink) 60%, transparent); border-radius: 999px;
  padding: 0.85em 1.6em; color: var(--ink); font-weight: 500;
  transition: background var(--dur) ease, color var(--dur) ease, border-color var(--dur) ease;
}
.btn-primary { background: var(--ink); border-color: var(--ink); color: var(--bg-deep); }
.btn:hover { background: var(--accent); border-color: var(--accent); color: var(--bg-deep); }
.btn:active { transform: translateY(1px); }
.cta-link {
  display: inline-flex; align-items: center; gap: var(--space-3); font-weight: 500;
  border-bottom: 1px solid var(--ink); padding-bottom: 3px; white-space: nowrap;
}
.cta-link .arrow { transition: transform var(--dur) var(--ease); }
.cta-link:hover .arrow { transform: translateX(6px); }

/* ============================================================
   Hero: the name, and the engineer in front of it
   ============================================================ */
.hero { position: relative; }
.hero-pin { position: relative; height: 100vh; height: 100svh; min-height: 36rem; overflow: hidden; }
/* While the portrait comes apart the hero holds still. That hold is CSS
   sticky, not a script pin: the browser keeps a sticky block in place on
   the same frame it scrolls, where a script pin switches to fixed one frame
   late and jumps at the start and end of the hold. The extra 65% of a
   screen is the length of the hold (home.js scrubs across it); it is a
   block, not padding, because a sticky element only travels within its
   parent's content box. */
html.motion .hero::after { content: ""; display: block; height: 65vh; height: 65svh; }
html.motion .hero-pin { position: sticky; top: 0; }
/* The composition lives in a frame that stops growing at 150rem and sits in
   the middle of wider screens. Inside it everything is sized in container
   units (cqw) against the frame, not the window, so on a 3440px ultrawide
   the name, the portrait and the copy keep the same relationship they have
   on a laptop instead of drifting a screen apart. */
.hero-frame { position: relative; height: 100%; max-width: 150rem; margin-inline: auto; container-type: inline-size; }
/* Landscape screens: the portrait on the left (he sits turned into the
   page, toward his name, rather than toward its edge), the name to its right,
   read in full, and the copy directly under it, so the right column reads
   top to bottom. The column starts a fixed gap after the portrait (whose
   width is its height, min(84svh, 42cqw)); the name is 5.75em wide (with
   the second line's indent), so its size is also capped by the width left
   after the column starts, keeping it clear of the section rail. */
.hero {
  --portrait-h: min(84svh, 42cqw);
  --col-left: calc(2.5cqw + var(--portrait-h) * 1.005 + 5cqw);
  --name-fs: min(8.8cqw, 17svh, (100cqw - var(--col-left) - 2.5cqw - 4.75rem) / 5.75);
}
.hero-name {
  position: absolute; left: calc(var(--col-left) - 2.5cqw); right: auto; top: 22%; transform: none;
  display: flex; flex-direction: column; padding-inline: 2.5cqw;
  font-size: var(--name-fs); font-weight: 650; line-height: 0.8; letter-spacing: -0.065em;
  text-transform: uppercase; color: var(--ink); pointer-events: none; user-select: none;
}
.hn { display: block; will-change: transform; }
.hn-1 { align-self: flex-start; }
/* Solid, not outlined: a stroke on a variable font draws the glyphs'
   internal overlap contours (visible as stray bars through every H). */
.hn-2 { align-self: flex-start; margin-left: 0.4em; color: var(--accent); }
.hero-avatar {
  position: absolute; bottom: 0; left: 2.5cqw; right: auto;
  height: var(--portrait-h); aspect-ratio: 1600 / 1592;
}
/* above the particle canvas (z-index 1): the photo fades out over the points */
.hero-avatar { z-index: 2; --ground: 1; container-type: inline-size; }
.hero-avatar img { position: relative; z-index: 2; width: 100%; height: 100%; object-fit: contain; object-position: 50% 100%; }
/* Depth: a warm key light falling on him from above (a glow behind the
   figure), and the floor he sits on: a pool of that light with the real
   floor of the original photograph (yahia-floor.webp: its real shadows
   and reflections, on a dark floor lit by a warm pool, reaching a quarter
   of the frame past each side so every chair leg stands on it). Both
   are exactly as visible as the photograph, frame by frame (--ground, set
   by home.js from the dissolve): they form with him and leave with him.
   The floor also reaches 12% of the photo's height below it, where its
   pool of light fades out, so lifting the photo (the scroll nudge) never
   shows the floor's edge; the photo's height is the box's, or 0.995 of its
   width where the box is taller than the photo (phones). */
.hero-avatar::before {
  content: ""; position: absolute; z-index: 0; inset: -14% -26% 4% -26%; pointer-events: none;
  background: radial-gradient(ellipse 46% 52% at 52% 40%, rgba(232, 178, 112, 0.17), rgba(232, 178, 112, 0.05) 55%, transparent 72%);
  opacity: var(--ground);
}
.hero-avatar::after {
  content: ""; position: absolute; z-index: 1; inset: 0 -25% calc(-0.12 * min(100%, 99.5cqw)); pointer-events: none;
  background: url("assets/img/hero3d/yahia-floor.webp?v=20261013a") 50% 100% / contain no-repeat;
  opacity: var(--ground);
}
/* Held back from first paint when the particles are going to assemble it,
   so it never flashes in and out. If the script never takes over, it
   appears on its own after a few seconds. */
html.motion:not(.hero-ready) .hero-avatar img { opacity: 0; animation: show-late 0.6s ease 9s forwards; }
/* the light on him and the floor with his shadows come with him, never
   before him (alone they read as dark shapes floating on the floor) */
html.motion:not(.hero-ready) .hero-avatar::before, html.motion:not(.hero-ready) .hero-avatar::after { opacity: 0; animation: show-late 0.6s ease 9s forwards; }
@keyframes show-late { to { opacity: 1; } }
.hero-copy {
  position: absolute; left: var(--col-left); top: calc(22% + var(--name-fs) * 1.6 + clamp(1.25rem, 4svh, 3rem));
  max-width: min(30rem, 40cqw); z-index: 2;
}
.kicker {
  display: block; font-family: var(--mono); font-size: var(--fs-label); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--accent-deep);
}
.hero-lede { margin-top: var(--space-4); color: var(--ink-2); font-size: 1.02rem; line-height: 1.55; }
/* what he does, under his name: a headline line of its own, on two lines,
   led by a short gold rule, the ampersand in gold italic */
.hero-role {
  margin: 0; font-size: clamp(1.45rem, 0.5rem + 1.9vw, 2.8rem); font-weight: 500;
  line-height: 1.12; letter-spacing: -0.025em; color: var(--ink);
}
.hero-role span { display: block; white-space: nowrap; }
.hero-role .hr-1 { display: flex; align-items: center; gap: 0.55em; }
.hero-role .hr-1::before { content: ""; flex: none; width: 1.6em; height: 2px; border-radius: 2px; background: var(--accent); }
.hero-role .hr-2 { padding-left: 2.15em; color: var(--ink-2); }
.hero-role em { font-style: italic; font-weight: 400; color: var(--accent-deep); padding-right: 0.08em; }

/* Where the slogan rests on the first screen: at its foot, only the top
   half of its first line above the bottom edge (the nudge lifts it to show
   a little more, never the whole line), within the screen's width, under
   the name and copy, not under him. This is
   an invisible copy that keeps the place and size; the one slogan travels
   here from its own section (home.js, pinStatement). Same lines, letters and
   spacing as .statement-text, so the travel is one uniform scale. */
.hero-peek {
  position: absolute; z-index: 1; left: var(--col-left);
  /* two lines, 2.04em tall: the top 0.5em shows (the upper half of the
     first line's letters) */
  bottom: -1.54em;
  margin: 0; pointer-events: none; visibility: hidden; width: max-content;
  font-size: clamp(1.8rem, 0.4rem + 3vw, 4.6rem);
}
html:not(.motion) .hero-peek { display: none; }
.hero-peek, .statement-text { font-weight: 600; line-height: 1.02; letter-spacing: -0.045em; }
.hero-peek em, .statement-text em { font-style: italic; font-weight: 500; padding-right: 0.04em; }
/* two lines on wide screens, four on phones (see the stacked layout) */
.hero-peek .sl, .statement-text .sl { display: block; white-space: nowrap; }
/* On a phone, and on any screen taller than it is wide (tablets upright, a
   monitor turned portrait), the hero is exactly one screen (it is held; a
   held block taller than the screen would hold its own buttons out of
   reach): name on top, the figure takes whatever height is left, copy and
   buttons below. */
@media (max-width: 820px), (orientation: portrait) and (max-aspect-ratio: 9/10) {
  .hero-pin { height: 100svh; min-height: 32rem; }
  .hero-frame { display: flex; flex-direction: column; padding-top: 6.1rem; }
  .hero-name { position: relative; left: auto; top: auto; transform: none; flex: none; font-size: clamp(3rem, 16.2vw, 12rem); padding-inline: var(--page-pad); }
  .hn-2 { align-self: flex-end; margin-left: 0; }
  .hero-avatar { position: relative; left: auto; right: auto; bottom: auto; translate: none; flex: 1 1 auto; min-height: 0; width: 100%; height: auto; aspect-ratio: auto; margin-top: -6vw; }
  /* bottom padding makes room for the slogan under the copy (two lines) */
  .hero-copy { position: relative; left: auto; top: auto; bottom: auto; flex: none; max-width: 48rem; padding: var(--space-3) var(--page-pad) calc(0.6 * clamp(1.8rem, 9.6vw, 3rem) + var(--space-3)); }
  /* four lines here (4.08em): again only the top 0.5em shows */
  .hero-peek { left: var(--page-pad); bottom: -3.58em; font-size: clamp(1.8rem, 9.6vw, 3rem); }
  .hero-peek .sq, .statement-text .sq { display: block; }
  .hero-lede { margin-top: var(--space-2); font-size: 0.95rem; line-height: 1.5; }
  .btn { padding: 0.75em 1.35em; }
}
/* Short phones (an SE, a Fold's cover screen): stacked, the copy would
   leave the portrait a sliver. Instead the portrait takes everything below
   the name, held up under it, and the copy sits over its lower part on a
   fade of the page colour. */
@media (max-width: 820px) and (max-height: 700px) and (orientation: portrait) {
  .hero-pin { min-height: 0; }
  .hero-name { font-size: clamp(2.6rem, 15vw, 8rem); }
  /* top: just under the two lines of the name (2 x line-height 0.8) */
  .hero-avatar { position: absolute; left: 0; right: 0; top: calc(6.1rem + clamp(2.6rem, 15vw, 8rem) * 1.6); bottom: 0; height: auto; margin: 0; }
  .hero-avatar img { object-position: 50% 12%; }
  /* the floor fitted like the photo */
  .hero-avatar::after { background-position: 50% 12%; }
  .hero-copy {
    margin-top: auto; z-index: 3; padding-top: 4.5rem;
    background: linear-gradient(to top, var(--bg) 0%, var(--bg) 58%, color-mix(in srgb, var(--bg) 70%, transparent) 80%, transparent);
  }
  .hero-lede { font-size: 0.9rem; }
  .hero-peek { z-index: 4; }
}
/* Phones and small tablets on their side (and an opened Fold): a screen
   this short has no room for a stack, so the portrait stands full height on
   the left, the name runs on one line across the top right and the copy sits
   bottom right, all on one screen. */
@media (max-height: 540px) and (orientation: landscape) {
  .hero-peek { display: none; }
  .hero-pin { min-height: 0; }
  .hero-frame { display: block; padding-top: 0; }
  .hero-name {
    position: absolute; top: calc(4.1rem + 2svh); left: auto; right: 0; transform: none;
    flex-direction: row; gap: 0.22em; font-size: min(6.4cqw, 15svh); padding-inline: var(--page-pad);
  }
  .hn-1, .hn-2 { align-self: auto; margin-left: 0; }
  .hero-avatar {
    position: absolute; left: 2cqw; right: auto; bottom: 0; top: auto; translate: none; margin: 0;
    height: min(calc(100svh - 3.4rem), 52cqw); width: auto; aspect-ratio: 1600 / 1592; flex: none;
  }
  .hero-avatar img { object-position: 50% 100%; }
  /* all the width right of the portrait (its width = its height, capped at 52cqw) */
  .hero-copy {
    position: absolute; left: auto; right: var(--page-pad); top: auto; bottom: 0.9rem; padding: 0; background: none;
    max-width: min(30rem, calc(100cqw - min(100svh - 3.4rem, 52cqw) - 2cqw - var(--page-pad) - 0.75rem));
  }
  .hero-role { font-size: clamp(1rem, 3.4svh, 1.4rem); }
  .hero-lede { margin-top: 0.4rem; font-size: 0.8rem; line-height: 1.42; }
  .btn { padding: 0.6em 1.15em; font-size: 0.88rem; min-height: 2.75rem; }
}
/* The smallest phones on their side (320-400px tall): a narrower portrait
   leaves the copy room for one-line buttons and a shorter paragraph. */
@media (max-height: 400px) and (orientation: landscape) {
  .hero-name { top: calc(3.9rem + 1svh); }
  .hero-avatar { height: min(calc(100svh - 3.4rem), 42cqw); }
  .hero-copy { max-width: min(30rem, calc(100cqw - min(100svh - 3.4rem, 42cqw) - 2cqw - var(--page-pad) - 0.75rem)); }
  .hero-role { font-size: clamp(0.95rem, 3.2svh, 1.2rem); }
  .hero-lede { font-size: 0.78rem; line-height: 1.38; }
  .btn { font-size: 0.82rem; padding: 0.55em 1em; min-height: 2.75rem; }
}



/* The section rail (home.js): a glass capsule on the right edge, like the
   top bar, holding one segment per section, each as long as its section.
   Sections read are solid gold; the one being read fills with gold as it
   goes, glowing at its leading edge. Nothing comes out of it while the
   page scrolls, so it never covers the content: pointing at the rail shows
   a glass label naming the current section, pointing at a segment names
   that one, clicking it goes there. */
.section-rail {
  position: fixed; z-index: 40; right: clamp(0.5rem, 1.2vw, 1.25rem); top: 50%; translate: 0 -50%;
  height: min(62vh, 32rem); width: 1.5rem; pointer-events: none; contain: layout style;
}
.srl-capsule {
  position: absolute; inset: 0; display: flex; flex-direction: column; gap: 5px; padding: 7px 0;
  border-radius: 999px; pointer-events: auto;
  background: color-mix(in srgb, #14110e 62%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.6), inset 0 1px 0 color-mix(in srgb, var(--ink) 8%, transparent);
}
.srl-seg {
  position: relative; display: block; min-height: 10px; margin: 0 auto; width: 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 16%, transparent);
  transition: width 0.35s var(--ease), background 0.35s ease;
}
/* a wider target than the bar itself */
.srl-seg::before { content: ""; position: absolute; inset: -3px -9px; }
.srl-seg.is-here { width: 8px; background: color-mix(in srgb, var(--ink) 24%, transparent); }
.srl-fill {
  position: absolute; inset: 0; border-radius: inherit; transform-origin: 50% 0; transform: scaleY(0);
  background: linear-gradient(to bottom, color-mix(in srgb, var(--accent) 70%, #fff 0%), var(--accent-deep));
  will-change: transform;
}
.srl-seg.is-past .srl-fill { transform: scaleY(1); opacity: 0.7; }
.srl-seg.is-here .srl-fill { box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 70%, transparent), 0 6px 10px -4px var(--accent); }
.srl-seg:hover { background: color-mix(in srgb, var(--ink) 34%, transparent); }
.srl-seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* a segment's name, on pointing at it */
.srl-tip {
  position: absolute; right: calc(100% + 1.1rem); top: 50%; translate: 6px -50%; white-space: nowrap; pointer-events: none;
  padding: 0.45rem 0.8rem; border-radius: 999px; font: 600 0.78rem/1 var(--mono); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink); background: color-mix(in srgb, #14110e 90%, transparent);
  border: 1px solid color-mix(in srgb, var(--ink) 14%, transparent);
  opacity: 0; transition: opacity 0.2s ease, translate 0.2s var(--ease);
}
.srl-tip b { color: var(--accent-deep); margin-right: 0.55em; }
.srl-seg:hover .srl-tip, .srl-seg:focus-visible .srl-tip { opacity: 1; translate: 0 -50%; }
/* the label of the section being read, on pointing at the rail */
.srl-label {
  position: absolute; right: calc(100% + 0.7rem); top: 0; display: flex; align-items: baseline; gap: 0.6rem;
  padding: 0.55rem 0.95rem 0.55rem 0.8rem; border-radius: 999px; white-space: nowrap; pointer-events: none;
  background: color-mix(in srgb, #14110e 72%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(140%); backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.7), 0 0 18px -6px color-mix(in srgb, var(--accent) 45%, transparent);
  opacity: 0; translate: 10px -50%;
  transition: transform 0.5s var(--ease), opacity 0.3s ease, translate 0.3s var(--ease);
}
.section-rail:hover .srl-label { opacity: 1; translate: 0 -50%; }
.section-rail:has(.srl-seg:hover) .srl-label { opacity: 0; }
.srl-num { font: 700 1.05rem/1 var(--mono); color: var(--accent-deep); font-variant-numeric: tabular-nums; }
.srl-text { font: 600 0.82rem/1 var(--mono); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink); }
.srl-label.roll .srl-num, .srl-label.roll .srl-text { animation: srl-roll 0.4s var(--ease); }
@keyframes srl-roll { from { opacity: 0; transform: translateY(0.5em); } }
/* A phone has no margin beside the content: the rail is a hairline of
   segments on the very edge, with no capsule, nothing to tap, and it shows
   only while the page is moving, fading out a moment after it stops. */
@media (max-width: 820px), (pointer: coarse) {
  .section-rail { right: 2px; height: min(56vh, 24rem); width: 4px; opacity: 0; transition: opacity 0.35s ease; }
  .section-rail.is-moving { opacity: 1; }
  .srl-capsule { gap: 3px; padding: 0; background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; pointer-events: none; }
  .srl-seg, .srl-seg.is-here { width: 3px; }
  .srl-seg::before { content: none; }
  .srl-tip, .srl-label { display: none; }
}

/* ============================================================
   Statement
   ============================================================ */
/* The slogan starts inside the bottom of the hero, so its words arrive as
   the portrait finishes coming apart instead of a screen later. */
/* The slogan box is transparent and has nothing to click, so it lets clicks
   through to whatever it overlaps. After it, a clear gap before About. */
.statement { position: relative; z-index: 1; pointer-events: none; }
/* Only while the hero is held (motion on): the hold is what makes room for
   the overlap. Without it (reduced motion, no script) the sections simply
   follow one another. */
html.motion .statement { margin-top: -44vh; margin-top: -44svh; margin-bottom: 0; }
@media (max-width: 820px), (orientation: portrait) and (max-aspect-ratio: 9/10) { html.motion .statement { margin-top: -47vh; margin-top: -47svh; } }
.statement-pin { min-height: 100vh; min-height: 100svh; display: flex; align-items: center; padding: var(--space-7) var(--page-pad); }
/* the slogan holds still the same way (sticky) while its words light up;
   a long hold, so they light slowly, word by word, as the page scrolls */
html.motion .statement::after { content: ""; display: block; height: 80vh; height: 80svh; }
/* once it has lit fully and been passed, the hold moves above the slogan:
   the same space, so the page keeps its length (no jump of the browser's
   scrollbar) and nothing on screen shifts, and scrolling back up passes the
   lit slogan without holding. Back at the very top it moves back (home.js). */
html.motion .statement.is-spent::after { height: 0; }
html.motion .statement.is-spent::before { content: ""; display: block; height: 80vh; height: 80svh; }
html.motion .statement-pin { position: sticky; top: 0; }
/* its own screen: as large as fits the width, two lines (four on phones) */
.statement-text {
  width: max-content; max-width: 100%; margin-inline: auto;
  font-size: min(8rem, calc((100vw - 2 * var(--page-pad)) / 11));
}
.statement-text em { color: var(--accent-deep); }
/* travelling between its corner and its own screen: fixed to the screen,
   placed by a transform from the top left (home.js, pinStatement) */
.statement-text.is-flying { position: fixed; left: 0; top: 0; margin: 0; transform-origin: 0 0; z-index: 1; }
@media (max-width: 820px), (orientation: portrait) and (max-aspect-ratio: 9/10) {
  .statement-text { font-size: min(6rem, calc((100vw - 2 * var(--page-pad)) / 5.7)); }
}
.statement-text .w { display: inline-block; }

/* ============================================================
   About
   ============================================================ */
.about-grid {
  display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: var(--space-7); margin-top: var(--space-6); align-items: start;
}
.about-stats { display: flex; flex-direction: column; gap: var(--space-5); }
.stat { border-top: 1px solid var(--line-strong); padding-top: var(--space-4); }
.stat-num {
  display: block; font-family: var(--mono); font-weight: 300; letter-spacing: -0.07em;
  font-size: clamp(5rem, 2rem + 10vw, 12rem); line-height: 0.85; color: var(--accent-deep);
  font-variant-numeric: tabular-nums;
}
.stat-label { display: block; margin-top: var(--space-3); color: var(--ink-3); font-family: var(--mono); font-size: var(--fs-label); letter-spacing: 0.08em; text-transform: uppercase; max-width: 26ch; }
.about-copy p { color: var(--ink-2); font-size: clamp(1.1rem, 1rem + 0.4vw, 1.3rem); line-height: 1.55; max-width: 36rem; }
.about-copy p + p { margin-top: var(--space-4); }
.about-copy .about-offduty { font-style: italic; color: var(--ink-3); }
@media (max-width: 820px) {
  .about-grid { grid-template-columns: 1fr; gap: var(--space-6); }
  .about-stats { flex-direction: row; gap: var(--space-4); }
  .stat { flex: 1; }
  .stat-num { font-size: clamp(3.6rem, 18vw, 6rem); }
}

/* ============================================================
   Workshop: the workshop itself, then the two action shots
   ============================================================ */
.workshop { position: relative; padding-top: clamp(3.5rem, 9vh, 6rem); padding-bottom: clamp(3.5rem, 9vh, 6rem); }
.workshop-head { margin-bottom: clamp(1.5rem, 4vh, 2.75rem); }
.workshop-head p { margin-top: var(--space-4); color: var(--ink-2); font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem); max-width: 36rem; }
.workshop-head p strong { color: var(--ink); }
/* One after the other on a narrow screen; side by side on a wide one, the
   grinder (whose sparks fly left, into the open) on the left. The effects
   canvas covers both, so sparks and chips are not clipped at a photo's edge. */
.sparks-stage {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(0.75rem, 1.4vw, 1.5rem);
  max-width: 124rem; margin-inline: auto; padding-inline: var(--page-pad);
}
.sparks-stage .fx-canvas { z-index: 2; }
.fx-panel { position: relative; margin: 0; overflow: hidden; border-radius: var(--radius); background: var(--bg-card); aspect-ratio: 4 / 4.2; }
.fx-panel img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; will-change: transform; }
.fx-panel-sparks img { object-position: 46% 72%; }
.fx-panel-drill img { object-position: 54% 70%; }
@media (min-width: 560px) { .fx-panel { aspect-ratio: 3 / 2; } }
@media (min-width: 900px) {
  .sparks-stage { grid-template-columns: minmax(0, 1.18fr) minmax(0, 1fr); }
  .fx-panel { aspect-ratio: auto; height: clamp(24rem, 72svh, 58rem); }
}
/* A phone on its side: side by side as well, each as tall as the screen allows. */
@media (min-width: 560px) and (max-height: 540px) and (orientation: landscape) {
  .sparks-stage { grid-template-columns: minmax(0, 1.18fr) minmax(0, 1fr); }
  .fx-panel { aspect-ratio: auto; height: calc(100svh - 5rem); min-height: 13rem; }
}

/* The workshop: lit and unlit versions of the same photo stacked, plus the
   glow of each ceiling tube; home.js switches the lights on. Without
   motion the lit photo simply shows. */
/* The whole frame, never cropped: as wide as the column allows, but never
   taller than most of the screen (then narrower, centred). */
.lights-panel {
  position: relative; margin: 0 auto clamp(0.75rem, 1.4vw, 1.5rem); overflow: hidden; border-radius: var(--radius);
  background: #07080a; aspect-ratio: 4 / 3; width: min(100%, 82svh * 4 / 3);
}
.lights-panel img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.lp-tube { mix-blend-mode: screen; pointer-events: none; }
html.motion .lp-on, html.motion .lp-tube { opacity: 0; }

/* ============================================================
   Toolbox
   ============================================================ */
/* side by side whenever the width allows: three columns, then two, one only on a phone */
.toolbox-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); gap: var(--space-4); align-items: start; }
/* the boxes stand off the page: a lighter fill, lit a little more at the
   top, a firmer edge with a faint highlight along the top and a soft shadow */
.toolbox-group, .toolbox-ai {
  background: linear-gradient(180deg, color-mix(in srgb, var(--ink) 6%, var(--bg-card)), color-mix(in srgb, var(--ink) 2%, var(--bg-card)));
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--ink) 8%, transparent), 0 14px 32px -16px rgba(0, 0, 0, 0.75);
}
.toolbox-group { padding: var(--space-5); }
.toolbox-group h3 {
  font-family: var(--mono); font-size: var(--fs-label); font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent-deep); margin-bottom: var(--space-5);
}
.tool-list { display: flex; flex-direction: column; gap: var(--space-4); }
.tool-item { display: flex; align-items: center; gap: var(--space-4); font-size: 1.02rem; flex-wrap: wrap; }
.tool-item img.t-logo { width: 34px; height: 34px; object-fit: contain; flex: none; filter: invert(0.92) brightness(1.15); }
.cert-badges { display: flex; flex-wrap: wrap; gap: var(--space-2); flex-basis: 100%; }
.cert-badge {
  display: inline-flex; align-items: center; gap: var(--space-2);
  border: 1px solid var(--line-strong); border-radius: 999px; padding: 0.25em 0.8em 0.25em 0.25em;
  transition: border-color var(--dur) ease, background var(--dur) ease;
}
.cert-badge:hover { border-color: var(--accent); background: var(--accent-soft); }
.cert-badge img { width: 26px; height: 26px; border-radius: 50%; object-fit: contain; }
.cert-badge span { font-family: var(--mono); font-size: 0.78rem; color: var(--ink-2); white-space: nowrap; }
/* AI: one full-width card above the three groups that reads as one flow:
   the tools, in the pairs that work together (each pair one capsule, the
   two halves touching), then an arrow ("builds"), then what is built with
   them, as tags of the same family. Top to bottom on narrow screens. */
.toolbox-ai { margin-bottom: var(--space-4); padding: var(--space-5); }
.toolbox-ai h3 {
  font-family: var(--mono); font-size: var(--fs-label); font-weight: 500; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent-deep); margin-bottom: var(--space-5);
}
.ai-flow { display: grid; grid-template-columns: auto minmax(4.5rem, 8rem) minmax(0, 1fr); align-items: center; gap: var(--space-4); }
/* both capsules as wide as the wider one, their halves equal, so the
   joins line up */
.ai-pairs { display: grid; gap: var(--space-3); justify-self: start; }
.ai-pair {
  display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--line-strong); border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 4%, transparent);
}
.ai-tool { display: flex; align-items: center; gap: 0.65rem; padding: 0.55rem 1.15rem 0.55rem 0.8rem; font-size: 1.02rem; white-space: nowrap; }
.ai-tool + .ai-tool { border-left: 1px solid var(--line-strong); padding-left: 1rem; }
.ai-tool img.t-logo { width: 26px; height: 26px; object-fit: contain; flex: none; filter: invert(0.92) brightness(1.15); }
/* the arrow from the tools to what they build */
.ai-link { position: relative; height: 1px; background: linear-gradient(to right, var(--line-strong), var(--accent)); }
.ai-link::after {
  content: ""; position: absolute; right: -1px; top: 50%; width: 9px; height: 9px;
  border-top: 1px solid var(--accent); border-right: 1px solid var(--accent); transform: translateY(-50%) rotate(45deg);
}
.ai-link span {
  position: absolute; left: 50%; bottom: 0.55rem; translate: -50% 0;
  font-family: var(--mono); font-size: var(--fs-label); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3);
}
.ai-tags { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.ai-tags li {
  border: 1px solid var(--line-strong); border-radius: 999px; padding: 0.55em 1.05em;
  font-size: 1rem; color: var(--ink); background: color-mix(in srgb, var(--ink) 4%, transparent);
}
@media (max-width: 900px) {
  .ai-flow { grid-template-columns: 1fr; gap: var(--space-3); }
  .ai-link { width: 1px; height: 3rem; margin-left: 1.6rem; background: linear-gradient(to bottom, var(--line-strong), var(--accent)); }
  .ai-link::after { right: auto; left: 50%; top: auto; bottom: -1px; transform: translateX(-50%) rotate(135deg); }
  .ai-link span { left: 0.9rem; bottom: auto; top: 50%; translate: 0 -50%; }
}
@media (max-width: 520px) {
  .ai-tags { gap: var(--space-2); }
  .ai-tags li { font-size: 0.92rem; padding: 0.5em 0.9em; }
}
@media (max-width: 380px) {
  .ai-tool { padding: 0.5rem 0.8rem 0.5rem 0.6rem; font-size: 0.95rem; gap: 0.5rem; }
  .ai-tool + .ai-tool { padding-left: 0.75rem; }
}

/* ============================================================
   Showroom: the work, a real sideways scroller
   ============================================================
   Moves only when you scroll it sideways (trackpad or touch swipe, mouse
   drag, the arrow buttons, or the arrow keys once focused); scrolling the
   page down never moves it. home.js only adds the turn-away of the
   neighbours, from the scroller's own position. */
.showroom {
  position: relative; padding: clamp(3.5rem, 9vh, 6rem) 0 clamp(2.5rem, 6vh, 4rem);
  /* each product's box: big, but always leaving room for its caption */
  --item: min(60vw, max(calc(100svh - 19rem), 17rem), 1150px);
  /* the gap between products, how small the ones beside the centre are
     (home.js reads it), and the arrows' size */
  --gap: clamp(1rem, 3.5vw, 4rem); --side: 0.5; --btn: 4rem;
}
.showroom-head { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-5); flex-wrap: wrap; width: 100%; }
/* a quiet line right under the title */
.sr-lede { margin: var(--space-3) 0 0; font-size: clamp(1rem, 0.95rem + 0.3vw, 1.2rem); color: var(--ink-2); }
/* the way to the Work page: a pill whose arrow sits in its own circle,
   which fills with the accent and nudges forward on hover */
.sr-cta {
  display: inline-flex; align-items: center; gap: 0.9rem; white-space: nowrap;
  padding: 0.45rem 0.45rem 0.45rem 1.35rem; border-radius: 999px;
  border: 1px solid var(--line-strong); background: color-mix(in srgb, var(--ink) 4%, transparent);
  color: var(--ink); font-weight: 500; letter-spacing: -0.01em;
  transition: border-color var(--dur) ease, background var(--dur) ease;
}
.sr-cta-arrow {
  display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%;
  background: var(--ink); color: var(--bg-deep);
  transition: background var(--dur) ease, transform 0.35s var(--ease);
}
.sr-cta-arrow svg { width: 1.1rem; height: 1.1rem; }
.sr-cta:hover, .sr-cta:focus-visible { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.sr-cta:hover .sr-cta-arrow, .sr-cta:focus-visible .sr-cta-arrow { background: var(--accent); transform: translateX(3px); }
.work-intro-note { margin: var(--space-3) 0 0; color: var(--ink-3); font-size: var(--fs-small); }
.showroom-stage { position: relative; margin-top: clamp(0.5rem, 2vh, 1.75rem); }
.cf-track {
  display: flex; gap: var(--gap); margin: 0; list-style: none;
  padding: 1.25rem calc(50% - var(--item) / 2) 0.25rem;
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none; outline: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}
.cf-track::-webkit-scrollbar { display: none; }
.cf-track:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius); }
.cf-track.is-dragging, .cf-track.is-peeking { scroll-snap-type: none; }
/* a hand that grabs: the row is something to take hold of and pull */
@media (hover: hover) and (pointer: fine) { .cf-track { cursor: grab; } .cf-track.is-grabbing { cursor: grabbing; } }

/* Arrows either side of the product in the centre, level with it, in the
   empty space between it and its smaller neighbours, so they never sit on a
   photo. The one there is nothing in the direction of is hidden. */
.sr-btn {
  position: absolute; z-index: 3; top: calc(1.25rem + var(--item) / 2); translate: 0 -50%;
  width: var(--btn); height: var(--btn); border-radius: 999px; display: grid; place-items: center; cursor: pointer;
  border: 1px solid rgba(207, 157, 92, 0.55); color: var(--ink);
  background: rgba(18, 16, 13, 0.62); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease, opacity 0.3s ease, scale 0.3s ease;
}
.sr-btn svg { width: 1.5rem; height: 1.5rem; }
/* centred in the space between the centre product's box and its
   neighbour's shrunken box: gap + item * (1 - side) / 2 wide */
.sr-prev { left: max(0.5rem, calc(50% - var(--item) / 2 - (var(--gap) + var(--item) * (1 - var(--side)) / 2) / 2 - var(--btn) / 2)); }
.sr-prev svg { rotate: 180deg; }
.sr-next { right: max(0.5rem, calc(50% - var(--item) / 2 - (var(--gap) + var(--item) * (1 - var(--side)) / 2) / 2 - var(--btn) / 2)); }
.sr-btn:hover { background: var(--accent); border-color: var(--accent); color: var(--bg); scale: 1.06; }
.sr-btn:disabled { opacity: 0; pointer-events: none; scale: 0.8; }

/* Which product, large, and where it sits in the row: a handle one
   product wide on a rail of one notch per product, that can be dragged. */
.sr-progress { display: flex; align-items: center; gap: clamp(1rem, 3vw, 2.5rem); margin-top: clamp(0.5rem, 1.6vh, 1.25rem); }
.sr-count { display: inline-flex; align-items: baseline; gap: 0.4rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sr-now {
  display: inline-block; font-size: clamp(2.6rem, 1.6rem + 2.8vw, 4.6rem); font-weight: 650; line-height: 0.9; letter-spacing: -0.05em;
  color: var(--accent-deep);
}
.sr-now.roll-up { animation: sr-roll-up 0.45s var(--ease); }
.sr-now.roll-down { animation: sr-roll-down 0.45s var(--ease); }
@keyframes sr-roll-up { from { transform: translateY(0.45em); opacity: 0; } }
@keyframes sr-roll-down { from { transform: translateY(-0.45em); opacity: 0; } }
.sr-total { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: 0.12em; color: var(--ink-3); }
.sr-rail {
  position: relative; flex: 1; height: 1.75rem; cursor: grab; touch-action: none;
  /* the notches: one per product, on a hairline */
  background:
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--ink) 30%, transparent) 0 1px, transparent 1px calc(100% / var(--n))) 0 50% / 100% 9px no-repeat,
    linear-gradient(var(--line), var(--line)) 0 50% / 100% 1px no-repeat;
}
.sr-rail.is-held { cursor: grabbing; }
.sr-thumb {
  position: absolute; left: 0; top: 50%; width: calc(100% / var(--n)); height: 6px; margin-top: -3px; border-radius: 999px;
  background: var(--accent); box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 55%, transparent);
  transition: height 0.2s ease, margin-top 0.2s ease;
}
.sr-rail:hover .sr-thumb, .sr-rail.is-held .sr-thumb { height: 10px; margin-top: -5px; }
.cf-item { flex: 0 0 var(--item); scroll-snap-align: center; }
.cf-item a { display: block; transform-origin: 50% 60%; will-change: transform; user-select: none; -webkit-user-drag: none; }
/* Every product sits on the same floor line: contained, anchored to the
   bottom of a square box. */
.cf-visual { position: relative; display: block; width: 100%; aspect-ratio: 1; }
.cf-visual img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: 50% 100%; pointer-events: none; }
.cf-visual .cf-img {
  filter:
    drop-shadow(-1px -1.5px 0.6px rgb(255 238 216 / calc(0.08 + 0.36 * var(--dark, 0.4))))
    drop-shadow(0 0 calc(14px + 30px * var(--dark, 0.4)) rgb(255 214 168 / calc(0.02 + 0.17 * var(--dark, 0.4))))
    drop-shadow(16px 20px 18px rgb(0 0 0 / 0.55));
}
/* the faint pool of studio light behind and under it, which the glow and
   the shadow read against (brighter for a darker product) */
.cf-visual:not(.is-photo)::before {
  content: ""; position: absolute; inset: 6% 2% -6%; pointer-events: none;
  background:
    radial-gradient(ellipse 58% 50% at 44% 52%, rgb(255 222 182 / calc(0.03 + 0.1 * var(--dark, 0.4))), transparent 72%),
    radial-gradient(ellipse 50% 9% at 56% 94%, rgb(255 226 196 / calc(0.035 + 0.06 * var(--dark, 0.4))), transparent 76%);
}
/* a project with only photographs: its main photo, framed */
.cf-visual.is-photo .cf-photo { object-fit: contain; object-position: 50% 100%; border-radius: var(--radius); }
.cf-visual.is-photo { display: flex; align-items: flex-end; justify-content: center; }
.cf-visual.is-photo .cf-photo { position: static; width: auto; height: auto; max-width: 100%; max-height: 100%; box-shadow: 0 24px 40px -22px rgba(0, 0, 0, 0.7); border: 1px solid var(--line); }
/* Its shadow on the floor is its own silhouette, flattened onto the floor
   line and darkened: as wide as the product is, wherever it is solid. */
.cf-floor { position: absolute; inset: 0; filter: blur(9px); opacity: 0.62; pointer-events: none; }
/* thrown down and to the right, away from the key light at the upper left */
.cf-floor img { transform: translateY(1.5%) skewX(-50deg) scaleY(0.09); transform-origin: 50% 100%; filter: brightness(0); }
.cf-caption { display: block; text-align: center; margin-top: clamp(1rem, 2.4vh, 1.75rem); }
.cf-title { display: block; margin-top: var(--space-2); font-size: clamp(1.2rem, 0.9rem + 1vw, 1.9rem); font-weight: 600; letter-spacing: -0.03em; line-height: 1.1; }
.cf-sub { display: block; margin-top: var(--space-1); color: var(--ink-3); font-size: var(--fs-small); }
.cf-versions {
  display: inline-block; margin-top: var(--space-2); font-family: var(--mono); font-size: 0.7rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--accent-deep); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); border-radius: 999px; padding: 0.3em 0.8em;
}
.cf-item a:hover .cf-title { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
@media (max-width: 700px) {
  /* narrow enough to leave each arrow its own margin beside the photo */
  .showroom { --item: min(calc(100vw - 2 * (var(--btn) + 2.25rem)), max(calc(100svh - 26rem), 16rem)); --btn: 2.75rem; }
  /* clear of the section rail on the right edge */
  .sr-next { right: 1.6rem; }
  .sr-btn svg { width: 1.2rem; height: 1.2rem; }
  .sr-progress { gap: var(--space-4); }
}

/* ============================================================
   Partners (card treatment as approved)
   ============================================================ */
.partners-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: var(--space-5); margin-top: var(--space-6); }
.partner-card { display: block; position: relative; }
/* the company's name, shown at once on hover (the browser's tooltip waits) */
.partner-name {
  position: absolute; left: 50%; bottom: calc(100% + 0.2rem); z-index: 2; pointer-events: none;
  /* never wider than its card (a card at the page's edge must not widen it) */
  width: max-content; max-width: 100%; text-align: center; line-height: 1.25;
  padding: 0.35rem 0.7rem; border-radius: 1rem;
  background: var(--ink); color: var(--bg-deep); font-size: var(--fs-small); font-weight: 500;
  box-shadow: 0 10px 24px -10px rgba(0,0,0,0.6);
  opacity: 0; translate: -50% 4px; transition: opacity 0.12s ease, translate 0.12s ease;
}
.partner-card:hover .partner-name, .partner-card:focus-visible .partner-name { opacity: 1; translate: -50% -6px; }
.partner-logo {
  position: relative; height: 8.5rem; display: flex; align-items: center; justify-content: center;
  background: var(--ink); border-radius: var(--radius); padding: var(--space-4);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
/* The lift is on the logo, not the card: the card's transform belongs to
   its entrance animation. The flag sits inside the logo, so it lifts too. */
.partner-card:hover .partner-logo, .partner-card:focus-visible .partner-logo { transform: translateY(-6px); box-shadow: 0 22px 36px -18px rgba(0,0,0,0.55); }
.partner-logo img { max-width: 85%; max-height: 78%; width: auto; height: auto; object-fit: contain; }
.partner-logo .flag {
  position: absolute; right: 0.6rem; bottom: 0.6rem; width: 22px; height: auto;
  border-radius: 3px; box-shadow: 0 0 0 2px var(--bg), 0 4px 10px rgba(0,0,0,0.4);
  overflow: hidden; line-height: 0;
}
.partner-logo .flag img { max-width: none; max-height: none; width: 100%; height: 100%; }
@media (max-width: 600px) {
  .partners-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
  .partner-logo { height: 5.75rem; padding: var(--space-3); }
  .partner-logo .flag { right: 0.35rem; bottom: 0.35rem; width: 16px; }
}

/* ============================================================
   Contact + footer
   ============================================================ */
.contact-section h2 { font-size: var(--fs-display); font-weight: 600; letter-spacing: -0.05em; line-height: 0.95; padding-bottom: 0.1em; max-width: 13ch; }
.contact-section .contact-sub { margin-top: var(--space-5); font-size: clamp(1.05rem, 1rem + 0.4vw, 1.3rem); color: var(--ink-2); max-width: 36rem; }
.contact-links { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); margin-top: var(--space-7); }
.contact-link { display: flex; flex-direction: column; gap: 0.5em; border-top: 1px solid var(--line-strong); padding-top: var(--space-4); }
/* Black and white marks: a white disc with a black glyph, inverted on hover. */
.contact-link .contact-icon {
  display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-radius: 50%;
  background: #f4f1ec; color: #0b0a09; margin-bottom: 0.35em;
  transition: background var(--dur) ease, color var(--dur) ease, box-shadow var(--dur) ease;
}
.contact-link .contact-icon svg { width: 1.3rem; height: 1.3rem; }
.contact-link:hover .contact-icon { background: #0b0a09; color: #f4f1ec; box-shadow: inset 0 0 0 1.5px #f4f1ec; }
.contact-link .contact-value { font-size: clamp(1.05rem, 0.9rem + 0.6vw, 1.45rem); color: var(--ink); transition: color var(--dur) ease; overflow-wrap: anywhere; }
.contact-link:hover .contact-value { color: var(--accent-deep); }
.contact-link:hover { border-color: var(--accent); }
@media (max-width: 820px) { .contact-links { grid-template-columns: 1fr; gap: var(--space-5); } }
footer.site-footer { padding-block: var(--space-5); border-top: 1px solid var(--line); }
.footer-inner { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--space-4); font-size: var(--fs-small); color: var(--ink-3); }
.footer-inner a { color: var(--ink-2); }

/* ============================================================
   Work page
   ============================================================ */
.work-intro { padding-block: 9rem var(--space-6); }
.work-intro h1 { font-size: min(var(--fs-mega), 15vw); font-weight: 650; letter-spacing: -0.065em; line-height: 0.82; text-transform: uppercase; padding-bottom: 0.08em; }
.field-nav { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-6); }
.field-nav a {
  font-family: var(--mono); font-size: var(--fs-label); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2);
  border: 1px solid var(--line-strong); border-radius: 999px;
  padding: 0.55em 1.1em; transition: border-color var(--dur) ease, color var(--dur) ease, background var(--dur) ease;
}
.field-nav a:hover { border-color: var(--accent); color: var(--ink); background: var(--accent-soft); }

.field-stage { position: relative; padding-block: var(--space-7); }
.field-stage-head {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2) var(--space-4); flex-wrap: wrap;
  border-top: 1px solid var(--line-strong); padding-top: var(--space-4); margin-bottom: var(--space-6);
}
.field-stage-head h2 { font-size: var(--fs-h2); font-weight: 600; letter-spacing: -0.035em; line-height: 1.05; }
.field-stage-head .field-count { font-family: var(--mono); font-size: var(--fs-label); color: var(--ink-3); letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap; }

.project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr)); gap: var(--space-5) var(--space-4); }
.project-tile { display: block; text-align: left; width: 100%; cursor: pointer; }
.tile-inner {
  position: relative; display: block; border-radius: var(--radius);
  transition: background var(--dur) ease;
}
.tile-visual {
  position: relative; display: flex; align-items: center; justify-content: center;
  aspect-ratio: 5 / 4; border-radius: var(--radius); overflow: hidden;
  background: var(--bg-card);
  border: 1px solid var(--line);
  transition: border-color var(--dur) ease;
}
.project-tile:hover .tile-visual, .project-tile:focus-visible .tile-visual { border-color: color-mix(in srgb, var(--accent) 50%, var(--line)); }
.tile-visual .tile-img { transition: transform 0.5s var(--ease), filter 0.5s var(--ease); }
.tile-visual.is-context .tile-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.tile-visual.is-cutout .tile-img {
  max-width: 80%; max-height: 80%; width: auto; height: auto; object-fit: contain;
  filter:
    drop-shadow(-1px -1.5px 0.6px rgb(255 238 216 / calc(0.08 + 0.36 * var(--dark, 0.4))))
    drop-shadow(0 0 calc(10px + 22px * var(--dark, 0.4)) rgb(255 214 168 / calc(0.02 + 0.17 * var(--dark, 0.4))))
    drop-shadow(10px 14px 12px rgb(0 0 0 / 0.55));
}
.tile-visual.is-cutout {
  background:
    radial-gradient(ellipse 62% 56% at 44% 46%, rgb(255 222 182 / calc(0.035 + 0.1 * var(--dark, 0.4))), transparent 72%),
    radial-gradient(ellipse 52% 12% at 56% 88%, rgb(255 226 196 / calc(0.03 + 0.05 * var(--dark, 0.4))), transparent 76%),
    var(--bg-card);
}
/* Hover: the product lifts toward you, the photo leans in a touch. CSS
   only, on the image (the tile's own transform belongs to its entrance). */
.project-tile:hover .tile-visual.is-cutout .tile-img, .project-tile:focus-visible .tile-visual.is-cutout .tile-img {
  transform: translateY(-8px) scale(1.05);
  filter:
    drop-shadow(-1px -1.5px 0.6px rgb(255 238 216 / calc(0.12 + 0.4 * var(--dark, 0.4))))
    drop-shadow(0 0 calc(12px + 26px * var(--dark, 0.4)) rgb(255 214 168 / calc(0.03 + 0.21 * var(--dark, 0.4))))
    drop-shadow(18px 26px 18px rgb(0 0 0 / 0.5));
}
.project-tile:hover .tile-visual.is-context .tile-img, .project-tile:focus-visible .tile-visual.is-context .tile-img { transform: scale(1.05); }
.tile-meta { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-3); padding: var(--space-4) var(--space-1) 0; }
.tile-title { display: block; font-weight: 600; font-size: 1.12rem; letter-spacing: -0.015em; line-height: 1.25; }
.tile-title .subtitle { display: block; margin-top: 4px; font-size: var(--fs-small); font-weight: 400; color: var(--ink-3); letter-spacing: 0; }
.tile-versions {
  flex: none; font-family: var(--mono); font-size: 0.74rem; font-weight: 500; color: var(--accent-deep);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); border-radius: 999px; padding: 0.3em 0.75em; white-space: nowrap;
}
/* A project with versions is a stack of cards, one edge per earlier
   version showing above it, and says how many on the photo. */
.project-tile { padding-top: 14px; }
.tile-stack { position: relative; display: block; }
.tile-stack::before, .tile-stack::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 40%; z-index: 0;
  border-radius: var(--radius); border: 1px solid var(--line-strong); background: color-mix(in srgb, var(--bg-card) 70%, var(--ink) 4%);
  transition: translate 0.35s var(--ease);
}
.tile-stack::before { translate: 0 -7px; scale: 0.94 1; }
.tile-stack::after { translate: 0 -14px; scale: 0.88 1; opacity: 0.7; }
.tile-stack[style*="--n: 2"]::after { display: none; }
.project-tile:hover .tile-stack::before { translate: 0 -10px; }
.project-tile:hover .tile-stack::after { translate: 0 -19px; }
.tile-stack .tile-visual { z-index: 1; }
.tile-badge {
  position: absolute; z-index: 2; top: 0.75rem; left: 0.75rem;
  font-family: var(--mono); font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--bg-deep); background: var(--accent-deep); border-radius: 999px; padding: 0.4em 0.85em;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}
.tile-arrow { display: inline-block; margin-top: var(--space-2); font-family: var(--mono); font-size: var(--fs-label); letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); transition: color var(--dur) ease; }
.project-tile:hover .tile-arrow { color: var(--accent-deep); }

/* ---------------- Project detail modal ---------------- */
.project-modal {
  position: fixed; inset: 0; z-index: var(--z-modal);
  display: flex; align-items: center; justify-content: center; padding: var(--space-5);
  opacity: 0; visibility: hidden; transition: opacity var(--dur) ease, visibility 0s var(--dur);
}
.project-modal.is-open { opacity: 1; visibility: visible; transition: opacity var(--dur) ease; }
.project-modal-backdrop { position: absolute; inset: 0; background: rgba(8,7,6,0.78); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.project-modal-panel {
  position: relative; z-index: 1; width: 100%; max-width: 70rem; max-height: 90vh; overflow-y: auto;
  background: var(--bg-card); border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: clamp(1.5rem, 4vw, 3.5rem);
}
.project-modal-close {
  position: absolute; top: var(--space-4); right: var(--space-4); z-index: 2;
  display: flex; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem;
  border-radius: 50%; background: var(--bg-deep); border: 1px solid var(--line);
  color: var(--ink); font-size: 1.4rem; line-height: 1; cursor: pointer;
  transition: border-color var(--dur) ease, color var(--dur) ease, transform var(--dur) var(--ease);
}
.project-modal-close:hover { border-color: var(--accent); color: var(--accent); transform: rotate(90deg); }
/* with a project open the page behind cannot move (wheel, touch, keys), and
   scrolling the project past its end does not carry on into the page */
html:has(body.modal-open), body.modal-open { overflow: hidden; }
.project-modal, .project-modal-panel { overscroll-behavior: contain; }
.project-modal-panel { max-height: 90svh; }
/* Small phones: the panel takes nearly the whole screen. */
@media (max-width: 480px) {
  .project-modal { padding: 0.5rem; }
  .project-modal-panel { padding: 1.1rem; max-height: calc(100svh - 1rem); }
  .project-modal-close { top: 0.6rem; right: 0.6rem; }
}

.detail-title { font-size: var(--fs-h1); font-weight: 600; letter-spacing: -0.04em; line-height: 1.02; padding-bottom: 0.08em; padding-right: 3rem; overflow-wrap: break-word; hyphens: auto; }
.detail-title .subtitle { display: block; margin-top: var(--space-3); font-size: 1rem; color: var(--ink-3); font-weight: 400; letter-spacing: 0; }
/* The versions: a labelled row of cards, each with that version's photo. */
.version-picker { margin-top: var(--space-5); }
.version-picker-label { display: block; font-family: var(--mono); font-size: var(--fs-label); letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent-deep); }
.version-tabs { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-3); }
.version-tab {
  display: flex; align-items: center; gap: 0.85rem; padding: 0.45rem 1.1rem 0.45rem 0.45rem; text-align: left;
  color: var(--ink-2); background: var(--bg-deep);
  border: 1px solid var(--line-strong); border-radius: calc(var(--radius) * 0.75);
  transition: border-color var(--dur) ease, color var(--dur) ease, background var(--dur) ease;
}
.version-thumb { position: relative; flex: none; width: 3.75rem; height: 3.75rem; border-radius: calc(var(--radius) * 0.5); overflow: hidden; background: var(--bg-card); display: grid; place-items: center; }
.version-thumb img { width: 100%; height: 100%; object-fit: cover; }
.version-tab.is-cutout .version-thumb img { width: 86%; height: 86%; object-fit: contain; }
.version-tab.is-cutout .version-thumb { background: none; box-shadow: inset 0 0 0 1px var(--line-strong); }
.version-name { display: flex; flex-direction: column; font-size: 1.35rem; font-weight: 650; letter-spacing: -0.03em; line-height: 1; }
.version-note { margin-top: 0.35rem; font-family: var(--mono); font-size: 0.68rem; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); }
.version-note:empty { display: none; }
.version-tab:hover { border-color: var(--ink-3); color: var(--ink); }
.version-tab.is-active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--bg-deep)); color: var(--ink); box-shadow: 0 0 0 1px var(--accent); }
.version-tab.is-active .version-note { color: var(--accent-deep); }
@media (max-width: 520px) {
  .version-tabs { display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); gap: var(--space-2); }
  .version-tab { flex-direction: column; align-items: stretch; gap: 0.5rem; padding: 0.4rem 0.4rem 0.6rem; }
  .version-thumb { width: 100%; height: auto; aspect-ratio: 1; }
  .version-name { align-items: center; font-size: 1.15rem; }
}

.stage-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-5); align-items: start; width: 100%; margin-top: var(--space-6); }
@media (min-width: 820px) { .stage-grid { grid-template-columns: minmax(0,1.1fr) minmax(0,0.9fr); gap: var(--space-7); } }
.stage-visual { display: flex; flex-direction: column; gap: var(--space-4); }
.stage-visual .visual-main { position: relative; aspect-ratio: 4/3.2; display: flex; align-items: center; justify-content: center; }
.stage-visual .visual-strip { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.stage-visual .visual-strip .visual-cell {
  position: relative; flex: 0 0 5.5rem; aspect-ratio: 1/1; border-radius: var(--radius-sm); overflow: hidden;
  padding: 0; border: 1px solid var(--line-strong); background: none; cursor: pointer;
  transition: transform var(--dur) ease, border-color var(--dur) ease;
}
.stage-visual .visual-strip .visual-cell:hover,
.stage-visual .visual-strip .visual-cell:focus-visible { transform: translateY(-3px); border-color: var(--accent); }
.stage-visual .visual-strip .visual-cell img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur) ease; }
.stage-visual .visual-strip .visual-cell:hover img { transform: scale(1.08); }
/* a cut-out sits in its frame on the page itself: the frame, no fill */
.stage-visual .visual-strip .visual-cell.is-cutout { display: flex; align-items: center; justify-content: center; background: none; }
.stage-visual .visual-strip .visual-cell.is-cutout img {
  width: auto; height: 100%; object-fit: contain; padding: var(--space-2);
  filter:
    drop-shadow(-0.5px -1px 0.3px rgb(255 236 212 / calc(0.08 + 0.36 * var(--dark, 0.4))))
    drop-shadow(0 0 calc(3px + 6px * var(--dark, 0.4)) rgb(255 214 168 / calc(0.03 + 0.2 * var(--dark, 0.4))))
    drop-shadow(3px 4px 4px rgb(0 0 0 / 0.5));
}
.stage-visual .visual-strip .visual-cell.is-current { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.stage-visual .visual-strip .visual-cell:not(.is-current) img { opacity: 0.62; transition: opacity var(--dur) ease, transform var(--dur) ease; }
.stage-visual .visual-strip .visual-cell:not(.is-current):hover img { opacity: 1; }
/* The main photo has two fixed arrows on its edges, back and on (the
   photo itself also moves on when clicked). */
.has-gallery .visual-main { cursor: pointer; overflow: visible; }
.has-gallery .visual-main:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; border-radius: var(--radius); }
.vm-arrow {
  position: absolute; z-index: 3; top: 50%; translate: 0 -50%; display: grid; place-items: center;
  width: 2.9rem; height: 2.9rem; padding: 0; border-radius: 50%; cursor: pointer;
  color: var(--ink); background: color-mix(in srgb, #14110e 60%, transparent); backdrop-filter: blur(10px) saturate(140%);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent); box-shadow: 0 10px 24px -10px rgba(0, 0, 0, 0.7);
  transition: background var(--dur) ease, border-color var(--dur) ease, color var(--dur) ease, scale 0.25s var(--ease);
}
.vm-arrow svg { width: 1.15rem; height: 1.15rem; }
.vm-prev { left: 0.6rem; }
.vm-prev svg { rotate: 180deg; }
.vm-next { right: 0.6rem; }
.vm-arrow:hover, .vm-arrow:focus-visible { background: var(--accent); border-color: var(--accent); color: var(--bg); scale: 1.06; outline: none; }
/* how many photos, and which: thin segments with a count */
.vm-meter { display: flex; align-items: center; gap: var(--space-4); margin-top: calc(var(--space-2) * -1); }
.vm-count { font-family: var(--mono); font-size: var(--fs-label); letter-spacing: 0.08em; color: var(--ink-3); white-space: nowrap; }
.vm-count b { color: var(--accent-deep); font-weight: 500; }
.vm-segs { display: flex; gap: 4px; flex: 1; max-width: 16rem; }
.vm-segs i { flex: 1; height: 2px; border-radius: 2px; background: color-mix(in srgb, var(--ink) 16%, transparent); transition: background 0.35s ease; }
.vm-segs i.is-past { background: color-mix(in srgb, var(--accent) 45%, transparent); }
.vm-segs i.is-on { background: var(--accent); }
.stage-visual .stage-img {
  position: absolute; inset: 0; margin: auto; max-width: 100%; max-height: 100%;
  width: auto; height: auto; object-fit: contain; z-index: 1;
  filter:
    drop-shadow(-1px -1.5px 0.6px rgb(255 238 216 / calc(0.08 + 0.36 * var(--dark, 0.4))))
    drop-shadow(0 0 calc(14px + 30px * var(--dark, 0.4)) rgb(255 214 168 / calc(0.02 + 0.17 * var(--dark, 0.4))))
    drop-shadow(16px 20px 18px rgb(0 0 0 / 0.55));
  will-change: transform, opacity;
}
.stage-visual .visual-main {
  background:
    radial-gradient(ellipse 58% 52% at 44% 48%, rgb(255 222 182 / calc(0.03 + 0.1 * var(--dark, 0.4))), transparent 72%),
    radial-gradient(ellipse 50% 10% at 56% 92%, rgb(255 226 196 / calc(0.03 + 0.05 * var(--dark, 0.4))), transparent 76%);
}
.stage-visual .stage-img.is-context { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius); filter: none; }
.stage-text .stage-body { color: var(--ink-2); max-width: 42rem; font-size: 1.05rem; }
.stage-text .stage-body p { color: var(--ink); font-size: 1.15rem; line-height: 1.55; }
.stage-text .stage-body p + ul { margin-top: var(--space-5); }
.stage-text .stage-body ul { display: flex; flex-direction: column; gap: var(--space-3); }
.stage-text .stage-body li { position: relative; padding-left: var(--space-5); }
.stage-text .stage-body li::before { content: ""; position: absolute; left: 0; top: 0.72em; width: 0.9rem; height: 1px; background: var(--accent); }

/* ============================================================
   Lifting a cut-out off the black page
   ============================================================
   Light, not shadow, separates a dark object from a dark ground. The key
   light is up and to the left (as on the hero): a rim along the edges that
   face it, a soft back-glow that follows the outline, both stronger the
   darker the object is (--dark, from assets/img/sized/photo-tone.js), and
   the object's own shadow thrown down and to the right, onto a faint pool
   of light so it can be seen. All of it drawn around the photo, never on
   it: the pixels stay the supplied ones. (Rules above: .cf-visual,
   .tile-visual.is-cutout, .stage-visual .stage-img and .visual-main,
   .visual-cell.is-cutout, .version-thumb.) */
.version-tab.is-cutout .version-thumb img {
  filter:
    drop-shadow(-0.5px -1px 0.3px rgb(255 236 212 / calc(0.08 + 0.36 * var(--dark, 0.4))))
    drop-shadow(0 0 calc(2px + 5px * var(--dark, 0.4)) rgb(255 214 168 / calc(0.03 + 0.2 * var(--dark, 0.4))))
    drop-shadow(2px 3px 3px rgb(0 0 0 / 0.5));
}
.tool-detail { display: block; margin-top: 0.15rem; font-size: 0.8rem; color: var(--ink-3); letter-spacing: 0.01em; }
