/* ==========================================================================
   RM CREATIVE — paper theme
   Warm off-white ground, near-black ink, one red accent, square corners
   everywhere, and a grain layer that actually moves.
   ========================================================================== */

/* ---------- fonts (self-hosted; no third-party request) ---------- */

@font-face {
  font-family: 'Antonio'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/antonio-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Antonio'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/antonio-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Antonio'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/fonts/antonio-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Antonio'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/fonts/antonio-latin-700-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 300; font-display: swap;
  src: url('/fonts/inter-latin-300-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/inter-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/inter-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/fonts/inter-latin-600-normal.woff2') format('woff2');
}

/* ---------- tokens ---------- */

:root {
  /* Paper — warm, never pure white, so the grain and the ink both read */
  --paper:    #f1ece2;
  --paper-2:  #e9e2d4;
  --paper-3:  #ded5c3;
  --paper-4:  #d2c8b2;

  /* Ink — warm near-black, not #000 */
  --ink:   #16130e;
  --ink-2: #4b463b;
  /* --ink-3 carries .muted and .form-note: the phone number, the email, the
     studio address, the small print under every form. It measured 3.21:1 on
     the card background — under the 4.5:1 a body size needs — so it is darkened
     here to 5.16:1 while keeping the same warm hue. --ink-4 is decorative only
     and now clears 3.2:1 rather than 2.0:1. */
  --ink-3: #615c51;
  --ink-4: #787267;

  --line:      #d7cebb;
  --line-soft: #e3dccd;
  --line-hard: #16130e;

  /* The one accent, carried over from the logo */
  --accent:      #d93a1e;
  --accent-dark: #b02c13;
  --accent-soft: rgba(217, 58, 30, 0.1);

  /* Inverted blocks (footer, CTA band) */
  --dark:    #16130e;
  --dark-2:  #221e17;

  --font-display: "Antonio", "Oswald", "Arial Narrow", sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, sans-serif;

  /* Square. Everywhere. */
  --radius-sm: 0px;
  --radius-md: 0px;
  --radius-lg: 0px;
  --radius-pill: 0px;

  --container: 1240px;
  --gutter: clamp(20px, 4vw, 48px);
  --space-section: clamp(72px, 10vw, 132px);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Names left over from the dark theme, still referenced by a few inline
     styles in generated markup. Mapped so nothing renders with an empty
     colour if one is missed. */
  --border: var(--line);
  --border-soft: var(--line-soft);
  --text-0: var(--ink);
  --text-1: var(--ink-2);
  --text-2: var(--ink-3);
  --text-3: var(--ink-4);
  --bg-0: var(--paper);
  --bg-1: var(--paper-2);
  --bg-2: var(--paper-2);
  --bg-3: var(--paper-3);
  --red-500: var(--accent);
}

/* ---------- reset ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  /* transparent, so the grain layer behind it shows through */
  background: transparent;
  color: var(--ink-2);
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; }

::selection { background: var(--accent); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ---------- live grain ----------
   A tiled noise PNG shifted in discrete steps. An SVG feTurbulence filter
   would repaint the whole viewport every frame; this is a few KB and moves
   on the compositor. */

/* The grain sits BEHIND the content, not over it — text, photographs and cards
   stay clean. That needs the paper colour to move up to <html>, so the layer
   has something to show against without body's own background hiding it. */
html { background: var(--paper); }

body::before {
  content: "";
  position: fixed;
  inset: -150%;
  z-index: -1;
  pointer-events: none;
  background-image: url('/images/grain.png');
  background-repeat: repeat;
  /* The tile is 256px of per-pixel noise drawn into 128 CSS px, so each grain
     speck is half a CSS pixel — fine film grain rather than visible dots, and
     it lands 1:1 on a 2x screen. Four times the unique area of the old 120px
     tile, so the repeat is no longer something the eye can pick out. */
  background-size: 128px 128px;
  opacity: 0.30;
  mix-blend-mode: multiply;
  animation: grain-shift 620ms steps(1) infinite;
  will-change: transform;
}

/* Deliberately uneven offsets and an odd number of steps: a regular cycle
   reads as a pulsing pattern, which is the opposite of grain. */
@keyframes grain-shift {
  0%    { transform: translate(0, 0); }
  9%    { transform: translate(-7%, 3%); }
  18%   { transform: translate(5%, -8%); }
  27%   { transform: translate(-2%, 9%); }
  36%   { transform: translate(8%, 1%); }
  45%   { transform: translate(-9%, -4%); }
  54%   { transform: translate(2%, 7%); }
  63%   { transform: translate(-5%, -9%); }
  72%   { transform: translate(9%, -2%); }
  81%   { transform: translate(-8%, 6%); }
  90%   { transform: translate(3%, -5%); }
  100%  { transform: translate(-4%, -7%); }
}

/* ---------- type ---------- */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 0.92;
  margin: 0;
}

h1 { font-size: clamp(3rem, 8.4vw, 7.2rem); }
h2 { font-size: clamp(2.1rem, 5.2vw, 4.2rem); }
h3 { font-size: clamp(1.15rem, 1.9vw, 1.5rem); letter-spacing: 0.005em; }
h4 { font-size: 0.95rem; letter-spacing: 0.08em; }

p { margin: 0; }

.lede {
  font-size: clamp(1.02rem, 1.5vw, 1.2rem);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 62ch;
}

/* ---------- vertical rhythm ----------
   The display face is set at line-height 0.92, so its ink overhangs the line
   box by roughly 0.19em top and bottom. A plain pixel margin therefore
   under-delivers by that much: measured across the site, an eyebrow sat 0px
   from the headline below it and a headline sat 0px off its own lede.

   So the rhythm is expressed on the HEADING, in the heading's own em — the one
   element whose font-size tracks the headline through every clamp — and sized
   to land on the intended optical gap once the overhang is subtracted.
   Adjacent margins collapse, so the larger of the two always wins. */

.eyebrow + h1, .pill + h1 { margin-top: 0.46em; }
.eyebrow + h2, .pill + h2 { margin-top: 0.46em; }
.eyebrow + h3, .pill + h3 { margin-top: 0.85em; }

h1:has(+ p), h1:has(+ .lede), h1:has(+ .btn-row), h1:has(+ .stats) { margin-bottom: 0.62em; }
h2:has(+ p), h2:has(+ .lede), h2:has(+ .btn-row), h2:has(+ .stats) { margin-bottom: 0.60em; }
h3:has(+ p), h4:has(+ p) { margin-bottom: 0.8em; }

/* Flex containers do not collapse margins and space their own children with a
   gap, so the rhythm must not stack on top of it. */
.product-body h3, .account-panel-head h3 { margin-bottom: 0; }
.product-body h3 + p, .account-panel-head h3 + p { margin-top: 0; }

.muted { color: var(--ink-3); }
.faint { color: var(--ink-4); }
.accent { color: var(--accent); }
.center, .text-center { text-align: center; }
.center-col { margin-left: auto; margin-right: auto; }
.max-w-prose { max-width: 66ch; }

.link-u {
  border-bottom: 1px solid var(--line);
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.link-u:hover { border-color: var(--accent); color: var(--accent); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 20px;
}
.eyebrow::before {
  content: "";
  width: 26px;
  height: 2px;
  background: var(--accent);
}

.mt-8 { margin-top: 8px; }
.mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; }
.mt-32 { margin-top: 32px; }
.mt-48 { margin-top: 48px; }
.mt-64 { margin-top: 64px; }

/* Headline lines that rise out of a mask on reveal.
   The display face is set at line-height 0.92, so the glyph box is TALLER than
   the line box it sits in — measured at 149px of text inside a 106px line.
   With overflow:hidden that shaved ~22px off the top and bottom of every
   headline. The padding gives the clip box the room the glyphs actually need
   and the matching negative margin takes it back out of the layout, so nothing
   moves. The hidden offset has to clear the padding too, hence 130% rather
   than 102%. */
.line-mask {
  display: block;
  overflow: hidden;
  padding-top: 0.22em;
  padding-bottom: 0.3em;
  margin-top: -0.22em;
  margin-bottom: -0.3em;
}
.line-mask > span {
  display: block;
  transform: translateY(145%);
  transition: transform 0.7s var(--ease);
  transition-delay: var(--d, 0ms);
}
.line-mask.in > span { transform: translateY(0); }

/* ---------- layout ---------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.section { padding: var(--space-section) 0; }
.section-tight { padding: clamp(48px, 6vw, 80px) 0; }

.section-head { max-width: 74ch; margin-bottom: clamp(36px, 5vw, 64px); }

.grid { display: grid; gap: clamp(16px, 2vw, 22px); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 880px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }

.split {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
.split-top { align-items: start; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; } }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }

/* ---------- buttons — square, minimal, bordered ---------- */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  --btn-bd: var(--line-hard);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 30px;
  border: 1px solid var(--btn-bd);
  border-radius: 0;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-body);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.34s var(--ease), border-color 0.34s var(--ease);
}

/* The fill wipes up from the bottom rather than cross-fading — it reads as
   deliberate at this weight of type. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--btn-hover-bg, var(--ink));
  transform: translateY(101%);
  transition: transform 0.42s var(--ease);
}
.btn:hover::before { transform: translateY(0); }
.btn:hover { color: var(--btn-hover-fg, var(--paper)); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.45; cursor: default; }
.btn:disabled::before { transform: translateY(101%); }

.btn-primary {
  --btn-bg: var(--accent);
  --btn-fg: #fff;
  --btn-bd: var(--accent);
  --btn-hover-bg: var(--ink);
  --btn-hover-fg: var(--paper);
}
.btn-primary:hover { border-color: var(--ink); }

.btn-outline,
.btn-ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  --btn-bd: var(--line-hard);
  --btn-hover-bg: var(--ink);
  --btn-hover-fg: var(--paper);
}

.btn-light {
  --btn-bg: var(--ink);
  --btn-fg: var(--paper);
  --btn-bd: var(--ink);
  --btn-hover-bg: var(--accent);
  --btn-hover-fg: #fff;
}
.btn-light:hover { border-color: var(--accent); }

.btn-block { display: flex; width: 100%; }
.btn-sm { padding: 11px 20px; font-size: 0.68rem; }

.btn-link {
  background: none;
  border: 0;
  padding: 0;
  margin-left: 14px;
  font-family: var(--font-body);
  font-size: 0.82rem;
  color: var(--ink-3);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.btn-link:hover { color: var(--accent); }

/* ---------- header ---------- */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 900;
  padding: 18px var(--gutter) 0;
  transition: transform 0.45s var(--ease);
}
.site-header.hide { transform: translateY(-130%); }

.nav {
  max-width: var(--container);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 12px 12px 12px 20px;
  border: 1px solid var(--line-hard);
  background: var(--paper);
}

.brand { display: flex; align-items: center; gap: 11px; margin-right: auto; }
.brand-mark { display: flex; }
.brand-mark img { width: 28px; height: 28px; }
.brand-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.16rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 26px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-links a {
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding: 6px 0;
  position: relative;
  transition: color 0.25s var(--ease);
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 0;
  height: 1px;
  background: var(--accent);
  transition: width 0.32s var(--ease);
}
.nav-links a:hover { color: var(--ink); }
.nav-links a:hover::after,
.nav-links a.active::after { width: 100%; }
.nav-links a.active { color: var(--ink); }

.nav-actions { display: flex; align-items: center; gap: 12px; }

.nav-cta {
  display: inline-flex;
  align-items: center;
  padding: 11px 22px;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--paper);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background 0.28s var(--ease), color 0.28s var(--ease), border-color 0.28s var(--ease);
}
.nav-cta:hover { background: var(--accent); border-color: var(--accent); color: #fff; }

.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line-hard);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

.nav-only-sm { display: none; }
/* The burger list turns .nav-only-sm back on below, and an author
   display rule beats the browser's own [hidden] { display: none }.
   Without this, a logged-in visitor on a phone was still shown Log In. */
.nav-links li[hidden] { display: none; }
.desktop-only { display: inline-flex; }

@media (max-width: 940px) {
  .nav { gap: 14px; padding: 10px 10px 10px 16px; }
  .nav-toggle { display: inline-flex; }
  .desktop-only { display: none; }
  .nav-only-sm { display: block; }

  .nav-links {
    position: fixed;
    top: 84px;
    left: var(--gutter);
    right: var(--gutter);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px;
    border: 1px solid var(--line-hard);
    background: var(--paper);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: opacity 0.3s var(--ease), transform 0.3s var(--ease), visibility 0.3s;
  }
  .site-header.menu-open .nav-links {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
  }
  .nav-links li { border-bottom: 1px solid var(--line-soft); }
  .nav-links li:last-child { border-bottom: 0; }
  .nav-links a { display: block; padding: 15px 12px; font-size: 0.8rem; }
  .nav-links a::after { display: none; }

  .site-header.menu-open::before {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(22, 19, 14, 0.4);
    z-index: -1;
  }
}

/* ---------- account menu in the header ---------- */

.nav-login {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding: 11px 4px;
  white-space: nowrap;
  transition: color 0.25s var(--ease);
}
.nav-login:hover { color: var(--accent); }

.account-menu { position: relative; display: flex; align-items: center; }

.account-trigger {
  display: flex;
  align-items: center;
  gap: 9px;
  height: 40px;
  padding: 0 12px 0 4px;
  border: 1px solid var(--line-hard);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.account-trigger:hover,
.account-menu.open .account-trigger { background: var(--ink); color: var(--paper); }

.account-face {
  width: 30px;
  height: 30px;
  flex: none;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--paper-3);
  color: var(--ink);
}
.account-face img { width: 100%; height: 100%; object-fit: cover; }

.account-name {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  max-width: 11ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.avatar-initials {
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  line-height: 1;
}

.account-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 244px;
  background: var(--paper);
  border: 1px solid var(--line-hard);
  padding: 0;
  z-index: 120;
}
.account-panel[hidden] { display: none; }

.account-panel-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--paper-2);
}
.account-panel-head strong {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--ink);
}
.account-panel-head span {
  font-size: 0.76rem;
  color: var(--ink-3);
  word-break: break-all;
}

.account-panel a,
.account-logout {
  display: block;
  width: 100%;
  text-align: left;
  padding: 13px 18px;
  border: 0;
  border-bottom: 1px solid var(--line-soft);
  background: none;
  font-family: var(--font-body);
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-2);
  cursor: pointer;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}
.account-panel a:hover { background: var(--ink); color: var(--paper); }

.account-logout {
  border-bottom: 0;
  color: var(--accent);
}
.account-logout:hover { background: var(--accent); color: #fff; }
.account-logout:disabled { opacity: 0.5; cursor: default; }

@media (max-width: 940px) {
  .nav-login { display: none; }
  .account-name { display: none; }
  .account-trigger { padding: 0 4px; }
  .account-panel { position: fixed; top: 84px; right: var(--gutter); left: auto; }
}

/* ---------- hero ---------- */

.hero {
  padding: clamp(150px, 20vh, 220px) 0 clamp(60px, 8vw, 100px);
  position: relative;
}

.hero-title-block { display: flex; flex-direction: column; gap: 0.03em; }
.hero-row { display: flex; align-items: center; gap: 0.24em; flex-wrap: wrap; }

.hero-media {
  height: 1.5em;
  width: auto;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: 1px solid var(--line-hard);
  flex: none;
}
.hero-media img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 700px) { .hero-media { height: 2em; } }

.hero-sub { max-width: 56ch; }

.hero-meta {
  margin-top: clamp(26px, 3.2vw, 40px);
  display: flex;
  flex-wrap: wrap;
  gap: 10px 30px;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.auth-hero {
  text-align: center;
  padding-top: clamp(128px, 17vh, 190px);
  padding-bottom: 0;
}
.auth-hero .eyebrow { justify-content: center; }
.auth-hero h1 { font-size: clamp(2.5rem, 6vw, 4.4rem); }
.auth-hero .lede { max-width: 46ch; margin-left: auto; margin-right: auto; text-wrap: balance; }
.auth-hero + .section-tight { padding-top: clamp(24px, 4vh, 40px); }

/* ---------- marquee ---------- */

.marquee {
  overflow: hidden;
  border-top: 1px solid var(--line-hard);
  border-bottom: 1px solid var(--line-hard);
  padding: 16px 0;
  background: var(--ink);
}
.marquee-track {
  display: flex;
  gap: 48px;
  width: max-content;
  animation: marquee 34s linear infinite;
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.6vw, 2rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--paper);
  white-space: nowrap;
}
.marquee-track span { display: inline-flex; align-items: center; gap: 48px; }
.marquee-track span::after {
  content: "";
  width: 9px;
  height: 9px;
  background: var(--accent);
}
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* ---------- cards ---------- */

.card {
  background: var(--paper-2);
  border: 1px solid var(--line);
  padding: clamp(24px, 3vw, 34px);
  position: relative;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.card:hover { border-color: var(--line-hard); background: var(--paper-3); }
.card:has(form):hover { background: var(--paper-2); border-color: var(--line); }

/* A display heading sitting straight on top of the first field label reads as
   one crowded block. The alert between them is usually hidden, so the gap has
   to be handled for each of the three orders these can appear in. */
.card > h3 + form,
.card > .auth-alert[hidden] + form,
.card > h3 + .auth-alert:not([hidden]) { margin-top: 22px; }

.card-num {
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 14px;
}

.icon-badge {
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-hard);
  color: var(--ink);
  margin-bottom: 18px;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 13px;
  border: 1px solid var(--line);
  background: var(--paper);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.pill-accent { background: var(--accent); border-color: var(--accent); color: #fff; }
.pill-soon { background: var(--paper-3); border-color: var(--line-hard); color: var(--ink-2); }
.pill-soon::before {
  content: "";
  width: 7px;
  height: 7px;
  border: 1px solid var(--ink-2);
}

.pill-live::before {
  content: "";
  width: 7px;
  height: 7px;
  background: var(--accent);
  animation: blip 2s infinite;
}
@keyframes blip {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

/* ---------- stats ---------- */

/* Dividers are drawn per cell, not as a parent background showing through the
   gaps — with three stats in a two-column grid the leftover cell used to paint
   a solid beige block. */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
  gap: 1px;
  background: transparent;
  border: 0;
}
.stat { background: var(--paper); padding: 26px 22px; box-shadow: 0 0 0 1px var(--line); }
.stat strong,
.stat b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 2.6vw, 2.5rem);
  overflow-wrap: break-word;
  hyphens: auto;
  font-weight: 700;
  line-height: 1;
  color: var(--ink);
}
.stat span {
  display: block;
  margin-top: 8px;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ---------- sticky stack ---------- */

.stack { display: flex; flex-direction: column; gap: 22px; }

.stack-item { position: sticky; top: 116px; }
/* Content was pinned to the bottom of a fixed 340px box, so a short card ended
   up with 74px of padding above and 53px below — the lopsided look. Centring
   inside a soft minimum keeps the padding equal whatever the copy length. */
.stack-card {
  border: 1px solid var(--line-hard);
  background: var(--paper-2);
  padding: clamp(30px, 4vw, 52px);
  min-height: clamp(240px, 24vw, 300px);
  display: flex;
  align-items: center;
  position: relative;
  overflow: hidden;
}
.stack-card.s2 { background: var(--paper-3); }
.stack-card.s3 { background: var(--ink); }
.stack-card.s3 h2, .stack-card.s3 h3 { color: var(--paper); }
.stack-card.s3 p { color: rgba(241, 236, 226, 0.78); }
.stack-card.s3 .card-num { color: var(--accent); }

/* The numeral is anchored to the card's own padding on the right and allowed to
   bleed off the bottom only. Clipping it on BOTH edges read as a mistake rather
   than a decision. */
.stack-card::after {
  content: attr(data-index);
  position: absolute;
  right: clamp(24px, 3vw, 44px);
  bottom: -0.24em;
  font-family: var(--font-display);
  font-size: clamp(7.5rem, 17vw, 14rem);
  font-weight: 700;
  line-height: 0.75;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--line);
  pointer-events: none;
}
.stack-card.s3::after { -webkit-text-stroke-color: rgba(241, 236, 226, 0.14); }

/* The dark card never restyled its button, so a near-black outline button sat on
   a near-black panel and was effectively invisible — the same treatment the CTA
   band already uses fixes it. */
.stack-card.s3 .btn-outline,
.stack-card.s3 .btn-ghost {
  --btn-bd: rgba(241, 236, 226, 0.42);
  --btn-fg: var(--paper);
  --btn-hover-bg: var(--paper);
  --btn-hover-fg: var(--ink);
}
.stack-card.s3 .btn-outline:hover,
.stack-card.s3 .btn-ghost:hover { border-color: var(--paper); }
.stack-card.s3 .link-u { color: var(--paper); border-color: rgba(241, 236, 226, 0.4); }

.stack-inner { position: relative; z-index: 1; max-width: 60ch; }

/* ---------- accordion ---------- */

.acc { border-top: 1px solid var(--line-hard); }
.acc-item { border-bottom: 1px solid var(--line); }

.acc-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 24px 4px;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  color: var(--ink);
  transition: color 0.25s var(--ease);
}
.acc-head:hover { color: var(--accent); }

.acc-num {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--ink-3);
  flex: none;
}
.acc-title {
  flex: 1;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2vw, 1.45rem);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.1;
}
.acc-icon {
  flex: none;
  width: 22px;
  height: 22px;
  position: relative;
}
.acc-icon::before,
.acc-icon::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1px;
  background: currentColor;
  transition: transform 0.35s var(--ease);
}
.acc-icon::after { transform: rotate(90deg); }
.acc-item.open .acc-icon::after { transform: rotate(0deg); }

.acc-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--ease);
}
.acc-item.open .acc-body { grid-template-rows: 1fr; }
.acc-body > div { overflow: hidden; }
.acc-body p { padding: 0 4px 26px 54px; max-width: 74ch; }
@media (max-width: 620px) { .acc-body p { padding-left: 4px; } }

/* ---------- forms ---------- */

.field { margin-bottom: 18px; }
.field label {
  display: block;
  margin-bottom: 8px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 300;
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease);
}
.field textarea { resize: vertical; min-height: 110px; }
.field input::placeholder,
.field textarea::placeholder { color: var(--ink-4); }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--ink);
  background: #fff;
}
.field input:disabled { background: var(--paper-3); color: var(--ink-3); cursor: not-allowed; }

.field-hint {
  margin: 7px 0 0;
  font-size: 0.76rem;
  color: var(--ink-3);
  line-height: 1.5;
}
.field-hint.weak { color: var(--accent); }
.field-hint.strong { color: #2f7a45; }

.form-note {
  margin-top: 14px;
  font-size: 0.78rem;
  color: var(--ink-3);
}
.form-note a { border-bottom: 1px solid var(--line); }
.form-note a:hover { color: var(--accent); border-color: var(--accent); }

.form-success {
  border: 1px solid var(--line-hard);
  background: var(--paper-3);
  padding: 26px;
}

/* Honeypot — off-screen rather than display:none, which some bots skip */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.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;
}

/* ---------- products ---------- */

.product-card {
  border: 1px solid var(--line);
  background: var(--paper-2);
  display: flex;
  flex-direction: column;
  transition: border-color 0.3s var(--ease);
}
.product-card:hover { border-color: var(--line-hard); }

.product-thumb {
  /* Portrait, because the admin panel locks every product photo to 3:4. A
     landscape box would crop the top and bottom off every one of them. */
  aspect-ratio: 3 / 4;
  border-bottom: 1px solid var(--line);
  background: var(--paper-3);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.product-thumb img { width: 100%; height: 100%; object-fit: cover; }
/* product names are long; keep the last line from stranding a single word */
.product-body h3 { text-wrap: balance; }
.product-body { padding: 24px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.product-body h3 + p { margin-top: 6px; }

.product-tag {
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.product-price-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: auto;
  padding-top: 14px;
}
.price {
  font-family: var(--font-display);
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--ink);
}
.price-strike { color: var(--ink-4); text-decoration: line-through; font-size: 0.9rem; }

/* ---------- testimonial video ---------- */

.testi-card {
  border: 1px solid var(--line);
  background: var(--paper-2);
  overflow: hidden;
  transition: border-color 0.3s var(--ease);
}
.testi-card:hover { border-color: var(--line-hard); }

.testi-video {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--ink);
  overflow: hidden;
}
.testi-video.reel { aspect-ratio: 9 / 16; }
.testi-video video,
.testi-video img { width: 100%; height: 100%; object-fit: cover; }

.video-play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border: 0;
  background: rgba(22, 19, 14, 0.25);
  cursor: pointer;
  transition: background 0.3s var(--ease);
}
.video-play::before {
  content: "";
  position: absolute;
  width: 66px;
  height: 66px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
  border: 1.5px solid rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  transition: background 0.3s var(--ease), transform 0.3s var(--ease);
}
.video-play::after {
  content: "";
  position: relative;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 10px 0 10px 17px;
  border-color: transparent transparent transparent #fff;
  margin-left: 5px;
}
.video-play:hover { background: rgba(22, 19, 14, 0.12); }
.video-play:hover::before { background: rgba(255, 255, 255, 0.34); transform: scale(1.06); }
.testi-video.playing .video-play { display: none; }

.video-fallback {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  padding: 8px 14px;
  background: var(--paper);
  border: 1px solid var(--line-hard);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
}

/* The name and the caption are two inline elements with nothing between
   them, so without this they run together as one line of text. */
.testi-meta { padding: 18px 20px; border-top: 1px solid var(--line); }
.testi-meta b,
.testi-meta strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--ink);
}
.testi-meta span {
  display: block;
  margin-top: 4px;
  font-size: 0.76rem;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ---------- tilt / parallax hosts ---------- */

.tilt { transform-style: preserve-3d; will-change: transform; }
.tilt-1x1 { aspect-ratio: 1 / 1; }
.tilt-4x5 { aspect-ratio: 4 / 5; }

.blob { display: none; }   /* the dark theme's glow blobs have no place on paper */
.blob-bl, .blob-br { display: none; }

/* ---------- CTA band ---------- */

.cta-band {
  background: var(--ink);
  border: 1px solid var(--ink);
  padding: clamp(44px, 6vw, 84px);
  text-align: center;
}
.cta-band h2, .cta-band h3 { color: var(--paper); }
.cta-band p { color: rgba(241, 236, 226, 0.8); }
.cta-band .eyebrow { color: rgba(241, 236, 226, 0.72); justify-content: center; }
.cta-band .btn-row {
  justify-content: center;
  margin-top: clamp(26px, 3vw, 38px);
}
.cta-band .btn-primary {
  --btn-bg: var(--accent);
  --btn-fg: #fff;
  --btn-bd: var(--accent);
  --btn-hover-bg: var(--paper);
  --btn-hover-fg: var(--ink);
}
.cta-band .btn-primary:hover { border-color: var(--paper); }
.cta-band .btn-ghost {
  --btn-bd: rgba(241, 236, 226, 0.42);
  --btn-fg: var(--paper);
  --btn-hover-bg: var(--paper);
  --btn-hover-fg: var(--ink);
}
.cta-band .btn-ghost:hover { border-color: var(--paper); }

/* ---------- footer ---------- */

.site-footer {
  background: var(--ink);
  color: rgba(241, 236, 226, 0.66);
  padding: clamp(56px, 7vw, 90px) 0 0;
  margin-top: clamp(60px, 8vw, 110px);
  overflow: hidden;
}
.site-footer .brand-name { color: var(--paper); }
.site-footer a { color: rgba(241, 236, 226, 0.66); transition: color 0.25s var(--ease); }
.site-footer a:hover { color: var(--accent); }

.footer-grid {
  display: grid;
  grid-template-columns: 1.5fr repeat(3, 1fr);
  gap: clamp(28px, 4vw, 52px);
}
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }

.footer-col h4 {
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  margin-bottom: 16px;
}
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.footer-col p { font-size: 0.88rem; line-height: 1.65; max-width: 40ch; }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: clamp(40px, 5vw, 64px);
  padding: 22px 0;
  border-top: 1px solid rgba(241, 236, 226, 0.14);
  font-size: 0.76rem;
}
.footer-legal { display: flex; flex-wrap: wrap; gap: 18px; }

/* Oversized wordmark bleeding off the bottom edge */
.footer-mark {
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(4rem, 17vw, 15rem);
  line-height: 0.78;
  letter-spacing: -0.02em;
  text-align: center;
  color: rgba(241, 236, 226, 0.07);
  margin: 0 calc(var(--gutter) * -1) -0.18em;
  user-select: none;
  pointer-events: none;
  white-space: nowrap;
}

/* ---------- floating WhatsApp ---------- */

.wa-float {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 880;
  width: 54px;
  height: 54px;
  display: grid;
  place-items: center;
  background: #1faa54;
  border: 1px solid var(--ink);
  transition: transform 0.3s var(--ease);
}
.wa-float:hover { transform: translateY(-3px); }

/* ---------- auth pages ---------- */

/* max-width applies to the padding box, so add the gutter back or the form
   loses ~96px of its width on desktop. */
.auth-shell { max-width: calc(460px + 2 * var(--gutter)); }

.auth-alert {
  border: 1px solid var(--accent);
  background: var(--accent-soft);
  color: var(--accent-dark);
  padding: 12px 15px;
  font-size: 0.85rem;
  line-height: 1.5;
  margin-bottom: 20px;
}
.auth-alert.good {
  border-color: #2f7a45;
  background: rgba(47, 122, 69, 0.09);
  color: #2f7a45;
}

.auth-divider {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 22px 0;
  color: var(--ink-4);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

/* The label is long and the button sits in a narrow card, so it needs tighter
   tracking and less side padding or it breaks onto a second line. */
.btn-google {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding-left: 16px;
  padding-right: 16px;
  letter-spacing: 0.08em;
  white-space: nowrap;
}
.btn-google svg { flex: none; }

/* ---------- OTP ---------- */

.otp-step { display: none; }
.otp-step.on { display: block; }

.otp-sent {
  border: 1px solid var(--line);
  background: var(--paper-3);
  padding: 13px 16px;
  font-size: 0.84rem;
  color: var(--ink-2);
  margin-bottom: 18px;
}
.otp-sent strong { color: var(--ink); }

.otp-boxes {
  display: flex;
  gap: 9px;
  margin-bottom: 8px;
}
.otp-boxes input {
  flex: 1;
  min-width: 0;
  height: 56px;
  padding: 0;
  text-align: center;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
}
.otp-boxes input:focus { outline: none; border-color: var(--ink); background: #fff; }

.otp-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 14px 0 18px;
  font-size: 0.78rem;
  color: var(--ink-3);
}

.verified-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #2f7a45;
}
.verified-badge::before {
  content: "";
  width: 7px;
  height: 7px;
  background: #2f7a45;
}

/* ---------- account pages ---------- */

.acct-avatar {
  width: 76px;
  height: 76px;
  flex: none;
  border: 1px solid var(--line-hard);
  background: var(--paper-3);
  overflow: hidden;
  display: grid;
  place-items: center;
}
.acct-avatar img { width: 100%; height: 100%; object-fit: cover; }
.acct-avatar .avatar-initials { font-size: 1.5rem; }

.acct-identity { display: flex; align-items: center; gap: 20px; }

.avatar-row {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 26px;
  flex-wrap: wrap;
}
.avatar-row .field-hint { max-width: 34ch; }

.order-list { list-style: none; margin: 16px 0 0; padding: 0; }
.order-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 15px 0;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.order-list li:last-child { border-bottom: 0; }
.order-list li > div { display: flex; flex-direction: column; gap: 3px; }
.order-list strong,
.order-list b { color: var(--ink); font-weight: 500; }
.order-list .muted { font-size: 0.8rem; }

/* ---------- reveal ---------- */

[data-anim] {
  opacity: 0;
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
  transition-delay: var(--d, 0ms);
}
[data-anim="up"] { transform: translateY(26px); }
[data-anim="fade"] { transform: none; }
[data-anim].in { opacity: 1; transform: none; }

.reveal { opacity: 0; transition: opacity 0.55s var(--ease); }
.reveal.in { opacity: 1; }

/* ---------- custom cursor ---------- */

/* Round on purpose — the square corners are a decision about buttons and
   panels, not about the pointer, which reads as a smudge when boxy.
   Both stay invisible until the first real mousemove, otherwise they park
   in the middle of the hero on load. */
.cursor-dot,
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s var(--ease), width 0.25s var(--ease),
              height 0.25s var(--ease), margin 0.25s var(--ease),
              background 0.25s var(--ease);
}
.cursor-dot.on, .cursor-ring.on { opacity: 1; }

.cursor-dot {
  width: 6px;
  height: 6px;
  background: var(--accent);
  margin: -3px 0 0 -3px;
}
.cursor-ring {
  width: 30px;
  height: 30px;
  border: 1px solid var(--ink);
  margin: -15px 0 0 -15px;
}
.cursor-ring.grow {
  width: 52px;
  height: 52px;
  margin: -26px 0 0 -26px;
  border-color: var(--accent);
}
.cursor-ring.down { transform-origin: center; border-color: var(--accent); }

/* A label lives inside the ring over anything carrying data-cursor. */
.cursor-ring.labelled {
  width: 74px;
  height: 74px;
  margin: -37px 0 0 -37px;
  background: var(--accent);
  border-color: var(--accent);
}
.cursor-ring.labelled::after {
  content: attr(data-label);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-body);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: #fff;
}
.cursor-ring.labelled + .cursor-dot,
.cursor-ring.labelled ~ .cursor-dot { opacity: 0; }

@media (pointer: coarse) {
  .cursor-dot, .cursor-ring { display: none; }
}

/* ---------- legal pages ---------- */

.legal { max-width: 74ch; }
.legal h2 { font-size: clamp(1.3rem, 2.4vw, 1.8rem); margin-top: 44px; }
.legal h3 { margin-top: 28px; }
.legal p, .legal li { color: var(--ink-2); }
.legal ul { padding-left: 20px; }
.legal li { margin-bottom: 8px; }

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  body::before { animation: none; }
  .line-mask > span { transform: none !important; }
  [data-anim] { opacity: 1 !important; transform: none !important; }
  .marquee-track { animation: none; }
}

/* ============================================================
   HERO FILM
   A single looping clip behind the top of the home page — from the
   very top of the document down to the black marquee bar, and no
   further. It is deliberately faint: the type has to stay the loudest
   thing on the page, and the grain layer runs over the top of it so
   the film reads as printed rather than played.
   ============================================================ */

/* .hero-stage starts at y=0 because the header is fixed and out of flow,
   so the film reaches the top of the document without any offset maths. */
.hero-stage { position: relative; }

.hero-film {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  /* Below the grain (body::before, z-index -1) so the grain multiplies over
     the film as well as the paper. Still above the root background. */
  z-index: -2;
}

.hero-film video,
.hero-film img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;

  /* The clip is a deep-blue night scene, and blue over warm cream turns the
     whole hero grey — the paper stops looking like paper. Forcing it to a warm
     monochrome instead makes it read as a sepia photograph printed on the
     page, which is the same language as the rest of the site and leaves the
     one red accent as the only colour on screen. */
  filter: grayscale(1) sepia(0.82) saturate(1.5) brightness(1.2);
  opacity: 0.66;

  /* Weighted to the upper right, where the layout is empty, and thinned right
     down over the text column on the left. This is what protects the reading
     contrast of the lede and the small print — without it the film has to be
     so faint everywhere that it stops being an image at all. */
  -webkit-mask-image: radial-gradient(118% 102% at 76% 26%,
      #000 10%, rgba(0, 0, 0, 0.60) 46%, rgba(0, 0, 0, 0.22) 80%, rgba(0, 0, 0, 0.10) 100%);
          mask-image: radial-gradient(118% 102% at 76% 26%,
      #000 10%, rgba(0, 0, 0, 0.60) 46%, rgba(0, 0, 0, 0.22) 80%, rgba(0, 0, 0, 0.10) 100%);
}

/* Two paper washes over the film. The first lightens the left third, where
   every word on the page sits — measured, not guessed: without it the eyebrow
   and the small print under the buttons fall to about 3:1 against the film,
   and body-size text needs 4.5:1. The second is heaviest at the foot, so the
   film settles into the page instead of running full strength into the
   marquee bar. */
.hero-film::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(101deg,
      rgba(241, 236, 226, 0.74) 0%,
      rgba(241, 236, 226, 0.66) 32%,
      rgba(241, 236, 226, 0.18) 62%,
      rgba(241, 236, 226, 0) 80%),
    linear-gradient(180deg,
      rgba(241, 236, 226, 0) 0%,
      rgba(241, 236, 226, 0.06) 58%,
      rgba(241, 236, 226, 0.30) 100%);
}

/* The two smallest labels in the hero — the eyebrow and the line under the
   buttons — carry --ink-3, which only clears 5.16:1 on bare paper. That is not
   enough headroom to also sit on a film, so on this one page they step down to
   --ink-2 and keep a real margin. */
.hero-stage .eyebrow,
.hero-stage .hero-meta { color: var(--ink-2); }

/* Below this the hero is one narrow column with the copy running the full
   width, so the left-to-right thinning has nowhere to go — measured at 900px,
   the lede ran out past the wash and into the strongest part of the film. Flat
   wash instead, and a little less film than the desktop layout carries. */
@media (max-width: 1000px) {
  .hero-film video,
  .hero-film img {
    opacity: 0.52;
    object-position: center 34%;
    -webkit-mask-image: radial-gradient(130% 80% at 50% 16%,
        #000 6%, rgba(0, 0, 0, 0.5) 44%, rgba(0, 0, 0, 0.16) 82%, rgba(0, 0, 0, 0.08) 100%);
            mask-image: radial-gradient(130% 80% at 50% 16%,
        #000 6%, rgba(0, 0, 0, 0.5) 44%, rgba(0, 0, 0, 0.16) 82%, rgba(0, 0, 0, 0.08) 100%);
  }
  .hero-film::after {
    background: linear-gradient(180deg,
      rgba(241, 236, 226, 0.20) 0%,
      rgba(241, 236, 226, 0.44) 34%,
      rgba(241, 236, 226, 0.38) 62%,
      rgba(241, 236, 226, 0.54) 100%);
  }
}

/* No autoplaying motion for anyone who has asked the system for less of it.
   The poster frame stays, so the composition is unchanged. */
@media (prefers-reduced-motion: reduce) {
  .hero-film video { display: none; }
}

/* ---------- cut-out portraits ---------- */

/* No frame, no fill — the photograph stands directly on the paper.
   The fade lives in the file's own alpha channel, not here: the source frame
   cropped his shoulders at both edges, so a CSS gradient down the bottom could
   never fix the dead-straight vertical cut down each SIDE. Masking again on
   top would only double the fade. */
.cutout {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: bottom center;
}
.tilt-1x1:has(.cutout),
.tilt-4x5:has(.cutout) {
  border: 0;
  background: none;
  position: relative;
  overflow: visible;
}

/* ============================================================
   CART
   ============================================================ */

.cart-badge {
  position: relative;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line-hard);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.cart-badge:hover { background: var(--ink); color: var(--paper); }

/* The count only appears once there is something to count. */
.cart-badge.has-items::after {
  content: attr(data-count);
  position: absolute;
  top: -7px;
  right: -7px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: #fff;
  font-family: var(--font-body);
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 1;
}

.cart-drawer { position: fixed; inset: 0; z-index: 1000; }
.cart-drawer[hidden] { display: none; }

.cart-scrim {
  position: absolute;
  inset: 0;
  background: rgba(22, 19, 14, 0.45);
  opacity: 0;
  transition: opacity 0.32s var(--ease);
}
.cart-drawer.on .cart-scrim { opacity: 1; }

.cart-panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(430px, 100%);
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border-left: 1px solid var(--line-hard);
  transform: translateX(100%);
  transition: transform 0.36s var(--ease);
}
.cart-drawer.on .cart-panel { transform: translateX(0); }

.cart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 24px;
  border-bottom: 1px solid var(--line-hard);
}
.cart-close {
  border: 0;
  background: none;
  font-size: 1.7rem;
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
  padding: 0 4px;
}
.cart-close:hover { color: var(--accent); }

.cart-body { flex: 1; overflow-y: auto; padding: 8px 24px; }
.cart-empty { padding: 40px 0; text-align: center; }

.cart-list { list-style: none; margin: 0; padding: 0; }
.cart-line {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "main amt" "qty remove";
  gap: 10px 14px;
  align-items: center;
  padding: 18px 0;
  border-bottom: 1px solid var(--line);
}
.cart-line:last-child { border-bottom: 0; }
.cart-line-main { grid-area: main; display: flex; flex-direction: column; gap: 3px; }
.cart-line-main strong,
.cart-line-main b { font-weight: 500; color: var(--ink); }
.cart-line-main .muted { font-size: 0.78rem; }
.cart-line-amt {
  grid-area: amt;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--ink);
}

.cart-qty { grid-area: qty; display: inline-flex; align-items: center; border: 1px solid var(--line); }
.cart-qty button {
  width: 30px;
  height: 30px;
  border: 0;
  background: none;
  color: var(--ink);
  font-size: 1rem;
  cursor: pointer;
}
.cart-qty button:hover { background: var(--ink); color: var(--paper); }
.cart-qty span { min-width: 30px; text-align: center; font-size: 0.85rem; }

.cart-remove {
  grid-area: remove;
  justify-self: end;
  border: 0;
  background: none;
  padding: 0;
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  cursor: pointer;
}
.cart-remove:hover { color: var(--accent); }

.cart-foot { padding: 20px 24px 24px; border-top: 1px solid var(--line-hard); background: var(--paper-2); }
.cart-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 16px;
}
.cart-total span {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.cart-total strong { font-family: var(--font-display); font-size: 1.9rem; font-weight: 700; color: var(--ink); }

.cart-done { padding: 26px 0; }
.cart-done h3 { margin-bottom: 4px; }

@media (max-width: 940px) {
  .cart-badge { width: 38px; height: 38px; }
}

/* A short bump so adding to the cart is felt without a panel taking over. */
.cart-badge.bump { animation: cart-bump 0.42s var(--ease); }
@keyframes cart-bump {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.16); }
  100% { transform: scale(1); }
}
/* ==========================================================================
   COURSES — catalogue, course page, and the locked player
   ========================================================================== */

/* ---------- course cards ---------- */

.course-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: clamp(20px, 3vw, 34px);
}

.course-card {
  border: 1px solid var(--line);
  background: var(--paper-2);
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.course-cover {
  aspect-ratio: 16 / 9;
  background: var(--paper-3);
  overflow: hidden;
  position: relative;
}
.course-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.course-cover .course-empty {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-size: 1.6rem; letter-spacing: 0.08em;
  color: var(--ink-4);
}

.course-body { padding: 20px 22px 24px; display: flex; flex-direction: column; flex: 1; }
.course-body h3 { font-size: 1.28rem; margin-bottom: 8px; }
.course-body .muted { flex: 1; }
.course-meta {
  display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: baseline;
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line-soft);
}
.course-price { font-family: var(--font-display); font-size: 1.5rem; line-height: 1; }
.course-count { font-size: 0.74rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3); }

/* ---------- one course's page ---------- */

.course-head { display: grid; grid-template-columns: 1.15fr 1fr; gap: clamp(28px, 4vw, 56px); align-items: start; }
@media (max-width: 900px) { .course-head { grid-template-columns: 1fr; } }

.course-buy {
  border: 1px solid var(--line-hard);
  background: var(--paper-2);
  padding: clamp(22px, 3vw, 30px);
  position: sticky;
  top: 108px;
}
@media (max-width: 900px) { .course-buy { position: static; } }

.syllabus { border: 1px solid var(--line); background: var(--paper-2); }
.syllabus-section + .syllabus-section { border-top: 1px solid var(--line); }
.syllabus-head {
  padding: 16px 20px;
  font-family: var(--font-display);
  font-size: 1.05rem; letter-spacing: 0.02em;
  background: var(--paper-3);
}
.syllabus-row {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 20px;
  border-top: 1px solid var(--line-soft);
  font-size: 0.95rem;
  min-width: 0;
}
.syllabus-row .t { flex: 1; min-width: 0; overflow-wrap: break-word; }
.syllabus-row .d { font-size: 0.78rem; color: var(--ink-3); white-space: nowrap; }
.syllabus-row .lock { width: 15px; height: 15px; flex: none; color: var(--ink-4); }
a.syllabus-row { text-decoration: none; color: inherit; }
a.syllabus-row:hover { background: var(--paper-3); }
.syllabus-row .free {
  font-size: 0.62rem; letter-spacing: 0.14em; text-transform: uppercase;
  border: 1px solid var(--accent); color: var(--accent); padding: 3px 7px; white-space: nowrap;
}

/* ---------- the player ----------
   The stack matters. The video at the bottom, an invisible shield above it so
   a right-click never reaches "Save video as", the watermark above that, and
   our controls on top. Nothing here stops a determined person — it stops the
   easy ways, and the watermark makes a copy traceable. */

.learn-wrap { max-width: 1320px; margin: 0 auto; padding: 104px var(--gutter) 80px; }
.learn-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: clamp(22px, 3vw, 38px); align-items: start; }
@media (max-width: 1000px) { .learn-grid { grid-template-columns: 1fr; } }

.vp {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  overflow: hidden;
  border: 1px solid var(--line-hard);
  user-select: none;
  -webkit-user-select: none;
}
.vp-shield { position: absolute; inset: 0; z-index: 3; cursor: pointer; background: transparent; }

.vp-mark {
  position: absolute;
  z-index: 4;
  pointer-events: none;
  font-family: var(--font-body);
  font-size: clamp(0.62rem, 1.1vw, 0.82rem);
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.34);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
  white-space: nowrap;
  transition: opacity 0.8s ease, left 0.8s ease, top 0.8s ease;
}

/* The picture itself when the lesson is a file: our own element, no other
   player's furniture anywhere near it. */
.vp-native {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  background: #000;
  display: block;
  object-fit: contain;
}
.vp-native[hidden] { display: none; }

/* The picture when the lesson lives on YouTube.
   --------------------------------------------------------------------------
   YouTube will not let its title, its channel name, its share button or its
   "Watch on YouTube" link be switched off — modestbranding stopped doing
   anything years ago. So they are not switched off, they are put where they
   cannot be seen.

   The window below is exactly the player's 16:9 box and it clips. The iframe
   inside it is made taller than that box by the same amount above and below,
   and then pulled up by half of that difference. YouTube always centres the
   picture in whatever box it is given, so the picture lands exactly over the
   window — nothing is cropped, nothing is zoomed, the video is full size — and
   YouTube's own strips, which it draws against the top and bottom edges of the
   IFRAME, end up outside the window entirely.

   pointer-events: none is the other half: no click can ever reach YouTube, so
   there is nothing to click through to. Everything the student presses is our
   own control bar, talking to the player through its API. */
.vp-yt {
  /* How much is clipped off the top and the bottom. It is symmetric, so the
     picture always lands exactly over the window whatever this is set to —
     which means it can be generous. The floor in pixels matters on a phone,
     where 16% of a short player is not enough to cover YouTube's strip. */
  --yt-chop: max(56px, 16%);
  position: absolute; inset: 0; z-index: 1;
  overflow: hidden;
  background: #000;
}
.vp-yt[hidden] { display: none; }
.vp-yt iframe {
  position: absolute;
  left: 50%;
  top: calc(-1 * var(--yt-chop));
  width: 100%;
  height: calc(100% + var(--yt-chop) * 2);
  transform: translateX(-50%);
  border: 0;
  pointer-events: none;
}

/* The play button, and where a message goes. See-through by default, so the
   video's own first frame is what the student looks at rather than a black
   wall. It only turns solid for a message, where the text has to be readable. */
.vp-cover {
  position: absolute; inset: 0; z-index: 2;
  display: grid; place-items: center;
  text-align: center; padding: 20px;
}
.vp-cover.solid { background: rgba(0, 0, 0, 0.62); }
/* Fully opaque, for the two moments a YouTube lesson is paused or has
   ended — which are exactly the two moments YouTube puts a grid of other
   people's videos on the screen. Nothing shows through this. */
.vp-cover.blackout { background: #000; }
.vp-cover[hidden] { display: none; }

.cover-play {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: rgba(255, 255, 255, 0.94);
  display: grid; place-items: center;
  filter: drop-shadow(0 2px 14px rgba(0, 0, 0, 0.6));
  transition: color 0.25s var(--ease), transform 0.25s var(--ease);
}
.cover-play:hover { color: var(--accent); transform: scale(1.06); }

.cover-msg {
  color: rgba(255, 255, 255, 0.86);
  font-family: var(--font-display);
  letter-spacing: 0.1em; text-transform: uppercase; font-size: 0.86rem;
  max-width: 34ch; line-height: 1.6;
}

.vp-bar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.72) 62%);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.vp:hover .vp-bar, .vp.show-bar .vp-bar { opacity: 1; }

.vp-btn {
  background: transparent; border: 0; padding: 6px; cursor: pointer;
  color: #fff; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 0;
}
.vp-btn:hover { color: var(--accent); }
.vp-btn svg { display: block; }

.vp-time { color: #fff; font-size: 0.74rem; letter-spacing: 0.06em; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Quality. There is a button here only when the lesson genuinely has more than
   one copy of the video — never a menu with one thing in it. */
.vp-q {
  font-family: var(--font-body);
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.1em;
  border: 1px solid rgba(255, 255, 255, 0.45);
  padding: 4px 9px; white-space: nowrap;
}
.vp-q[hidden] { display: none; }

.vp-qmenu {
  position: absolute; right: 46px; bottom: 46px; z-index: 6;
  background: rgba(0, 0, 0, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.28);
  display: flex; flex-direction: column; min-width: 92px;
}
.vp-qmenu[hidden] { display: none; }
.vp-qitem {
  background: none; border: 0; cursor: pointer;
  color: rgba(255, 255, 255, 0.86);
  font-family: var(--font-body); font-size: 0.74rem; letter-spacing: 0.08em;
  padding: 9px 14px; text-align: left; white-space: nowrap;
}
.vp-qitem:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.vp-qitem.on { color: var(--accent); }

.vp-seek {
  flex: 1; height: 26px; appearance: none; -webkit-appearance: none;
  background: transparent; cursor: pointer; min-width: 60px;
}
.vp-seek::-webkit-slider-runnable-track { height: 4px; background: rgba(255,255,255,0.32); }
.vp-seek::-moz-range-track { height: 4px; background: rgba(255,255,255,0.32); }
.vp-seek::-webkit-slider-thumb {
  -webkit-appearance: none; width: 13px; height: 13px; margin-top: -4.5px;
  background: var(--accent); border: 0; border-radius: 50%;
}
.vp-seek::-moz-range-thumb { width: 13px; height: 13px; background: var(--accent); border: 0; border-radius: 50%; }
.vp-seek:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---------- the lesson rail ---------- */

.rail { border: 1px solid var(--line); background: var(--paper-2); max-height: 74vh; overflow-y: auto; }
@media (max-width: 1000px) { .rail { max-height: none; } }
.rail-head { padding: 16px 18px; border-bottom: 1px solid var(--line); background: var(--paper-3); }
.rail-head strong { font-family: var(--font-display); font-size: 1.05rem; letter-spacing: 0.02em; }
.rail-sec { padding: 13px 18px 6px; font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3); }
.rail-item {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 11px 18px; text-decoration: none; color: var(--ink);
  border-top: 1px solid var(--line-soft); font-size: 0.92rem;
  min-width: 0;
}
.rail-item:hover { background: var(--paper-3); }
.rail-item.on { background: var(--paper-3); box-shadow: inset 3px 0 0 var(--accent); }
.rail-item .n { color: var(--ink-4); font-variant-numeric: tabular-nums; flex: none; }
.rail-item .t { flex: 1; min-width: 0; overflow-wrap: break-word; }
.rail-item .d { color: var(--ink-3); font-size: 0.74rem; flex: none; }

/* ---------- reviews from the panel ---------- */

.review-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: clamp(18px, 2.4vw, 28px); }
.review-card { border: 1px solid var(--line); background: var(--paper-2); display: flex; flex-direction: column; min-width: 0; }
.review-still { aspect-ratio: 16 / 9; position: relative; background: var(--ink); overflow: hidden; cursor: pointer; border: 0; padding: 0; width: 100%; }
.review-still img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0.92; }
.review-still .play {
  position: absolute; inset: 0; display: grid; place-items: center;
  color: #fff; background: rgba(0, 0, 0, 0.2);
}
.review-still:hover .play { background: rgba(0, 0, 0, 0.08); }
.review-body { padding: 16px 18px 20px; }
.review-body h4 { font-family: var(--font-display); font-size: 1.05rem; letter-spacing: 0.02em; }
.review-body .role { font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); margin-top: 4px; }
.review-body p { margin-top: 10px; font-size: 0.92rem; }

@media (pointer: coarse) {
  .vp-bar { opacity: 1; }
  .vp-btn { padding: 10px; }
  .rail-item { padding: 14px 18px; }
}

@media (prefers-reduced-motion: reduce) { .cart-badge.bump { animation: none; } }

/* ============================================================
   EVERY SCREEN
   Everything below came out of measuring the real pages at fourteen
   widths from 320px to 2200px, not from looking at two of them.
   ============================================================ */

/* --- 1. sideways scroll on small phones ---
   A flex or grid child defaults to min-width:auto, so one unbreakable string —
   an email address, a URL — sets the floor for its whole row and pushes the
   document wider than the screen. Measured: /contact scrolled 30px sideways at
   320px, and the cause was the single word rahulmevada143@gmail.com. */
.card > *,
.split > *,
.footer-grid > *,
.stats > * { min-width: 0; }

.card p,
.card h3,
.card li,
.footer-col li,
.footer-col p,
.footer-col a { overflow-wrap: break-word; }

/* The wordmark bleeds past the gutters on purpose, but below roughly 340px the
   clamp floor makes it wider than the screen too. Clip it at the footer rather
   than let it scroll the page. */
.site-footer { overflow: hidden; }

/* --- 2. label sizes on phones ---
   The uppercase labels sit between 10.6px and 11.2px. That is fine on a
   monitor and hard work on a phone at arm's length, so the floor comes up
   on every handheld width — with the letter-spacing eased at the same time,
   because wide tracking at a small size is what makes it hard to read, not the
   size alone. Desktop keeps the editorial scale it was designed with. */
@media (max-width: 820px) {
  .eyebrow    { font-size: 0.76rem; letter-spacing: 0.16em; }
  .pill       { font-size: 0.73rem; letter-spacing: 0.11em; }
  .stat span  { font-size: 0.74rem; letter-spacing: 0.12em; }
  .btn        { font-size: 0.8rem;  letter-spacing: 0.1em; }
  .hero-meta  { font-size: 0.76rem; letter-spacing: 0.11em; }
  .tick       { font-size: 0.7rem;  letter-spacing: 0.14em; }
}

/* --- 3. tap targets ---
   A fingertip needs about 44px. Measured on a touch viewport, these were
   between 20px and 38px tall: fine with a mouse, a miss with a thumb. */
@media (pointer: coarse) {
  .cart-badge { width: 44px; height: 44px; }
  .brand { min-height: 44px; }
  .link-u { display: inline-block; padding: 7px 0; }
  .footer-legal a,
  .footer-col ul a { display: inline-block; padding: 10px 0; }
  .footer-legal { gap: 10px 20px; }
  .footer-col ul { gap: 0; }
}

/* --- 4. short landscape screens ---
   A phone on its side is around 380px tall. The hero's top padding has a
   150px floor, which eats most of that before the headline even starts. */
@media (max-height: 620px) and (orientation: landscape) {
  .hero {
    padding-top: clamp(92px, 15vh, 150px);
    padding-bottom: clamp(34px, 6vh, 60px);
  }
  .auth-hero { padding-top: clamp(88px, 14vh, 140px); }
  .hero-film video,
  .hero-film img { object-position: center 30%; }
}

/* --- 5. the hero on a narrow phone ---
   Two things measured badly at 390px. The eyebrow wrapped to a second line
   with its red rule stranded beside the first, which reads as a mistake; and
   the two buttons sat side by side at different widths, which reads as
   sloppy. Both are handled by giving them the full column. */
@media (max-width: 560px) {
  .hero-stage .eyebrow {
    display: block;
    /* .center is a utility on this span; with the eyebrow switched to a block
       it would suddenly start centring text the headline does not centre. */
    text-align: left;
    text-wrap: balance;
  }
  .hero-stage .eyebrow::before {
    display: block;
    margin: 0 0 12px;
  }

  .hero .btn-row { flex-direction: column; align-items: stretch; }
  .hero .btn-row .btn { width: 100%; }
}

/* ---------- product video ----------
   The clip lives on YouTube. Nothing is loaded from there until Watch is
   pressed, so the shop page stays fast and sets no third-party cookie on
   anyone who never opens one. */

.thumb-play {
  position: absolute;
  left: 12px;
  bottom: 12px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--line-hard);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  padding: 8px 13px;
  font-family: var(--font-body);
  font-size: 0.63rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
.thumb-play:hover { background: var(--ink); color: var(--paper); }
/* 35px tall is fine under a mouse and a miss under a thumb. */
@media (pointer: coarse) { .thumb-play { padding: 12px 15px; } }
.product-thumb { position: relative; }

.video-modal {
  position: fixed;
  inset: 0;
  z-index: 1100;
  display: grid;
  place-items: center;
  padding: var(--gutter);
  background: rgba(22, 19, 14, 0.82);
}
.video-modal[hidden] { display: none; }
.video-box {
  position: relative;
  width: min(960px, 100%);
  aspect-ratio: 16 / 9;
  background: var(--ink);
  border: 1px solid var(--line-hard);
}
.video-box iframe { width: 100%; height: 100%; border: 0; display: block; }
.video-close {
  position: absolute;
  top: -46px;
  right: 0;
  width: 38px;
  height: 38px;
  border: 1px solid rgba(241, 236, 226, 0.5);
  background: none;
  color: var(--paper);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}
.video-close:hover { background: var(--paper); color: var(--ink); }
/* On a short screen the close button has nowhere to sit above the frame. */
@media (max-height: 520px), (max-width: 560px) {
  .video-close { top: 4px; right: 4px; border-color: rgba(241, 236, 226, 0.7); background: rgba(22, 19, 14, 0.7); }
}

/* A vector placeholder in a photo slot: show the whole drawing rather than
   cropping a wide graphic into a tall box. Real product photos are 3:4 and
   fill the frame as normal. */
.product-thumb img[src$=".svg"] { object-fit: contain; padding: 12%; }

/* Progress while a lesson video is going up. It is the only feedback there is
   on a job that can take minutes, so it is deliberately plain and obvious. */
.up-bar {
  margin-top: 10px; height: 8px; border-radius: 99px;
  background: rgba(0, 0, 0, 0.12); overflow: hidden;
}
.up-bar[hidden] { display: none; }
.up-fill {
  height: 100%; width: 0%;
  background: var(--accent);
  transition: width 0.25s linear;
}
