/* SUPERNOVA — core design system
   Extracted from the approved Direction A build. Layout + motion are
   intentionally NOT client-editable; only content is exposed via Elementor. */

:root{
    --black:#0B0A09;          /* warm black — the "warm grey/black tone" client liked */
    --panel:#100F0D;
    --fg:#FFFFFF;
    --dim:#9C978E;            /* warm grey, legible */
    --faint:#6A655C;
    --hair:rgba(255,255,255,0.09);
    --paper:#EFEDE7;          /* warm light section */
    --ink:#1A1815;
    --paper-dim:#726C62;
    --blue:#00a8e2;           /* reserved for one purposeful accent only */
    --ease:cubic-bezier(0.22,1,0.36,1);
    --edge:clamp(28px,6vw,140px);
    --maxw:1360px;
  }

/* ---------------------------------------------------------------
 * Scroll.
 *
 * The Lenis runtime styles that used to live here are gone along with
 * the library. One of them, `.lenis-stopped { overflow:hidden }`, is a
 * hard scroll lock keyed off a class Lenis puts on <html> — so if the
 * library ever mismeasured the page, the page froze. The reset below
 * defuses that permanently: even if a stale cached script or a browser
 * back/forward cache restores one of those classes, scrolling stays on.
 * -------------------------------------------------------------- */
html.lenis, html.lenis body,
html.lenis-stopped, html.lenis-smooth {
  overflow: visible !important;
  height: auto !important;
  position: static !important;
}


  *{box-sizing:border-box; margin:0; padding:0;}
  html{scroll-behavior:smooth;}   /* native; Lenis no longer intercepts anchors */
  body{background:var(--black); color:var(--fg);
    /* ★ Inter FIRST, then Helvetica.
       The stack was "Helvetica Neue","Inter",... — Helvetica Neue first — so
       Macs rendered Helvetica Neue while Windows and Android got Inter or
       Arial, and Inter was downloaded on every page and never used on a Mac.
       That platform split is the typography inconsistency the UX review
       reported on the Journal page. Inter is a neo-grotesque in the same
       family of forms, so this honours the Charte (which sanctions Helvetica
       as the fallback) while giving every visitor the same face. */
    font-family:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;
    -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; line-height:1.5;}
  img{display:block; max-width:100%;}
  a{color:inherit; text-decoration:none;}
  ::selection{background:rgba(0,168,226,0.22);}
  a:focus-visible{outline:1px solid var(--blue); outline-offset:4px;}

  /* very fine film grain — keeps the warm tone from going flat */
  body::after{content:""; position:fixed; inset:0; z-index:9990; pointer-events:none; opacity:.03;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}

  .wrap{max-width:var(--maxw); margin:0 auto; padding:0 var(--edge);}
  /* SMALL uppercase Swiss labels — the only place the condensed face appears */
  .label{font-family:"Oswald",sans-serif; font-weight:400; font-size:11px; letter-spacing:0.32em; text-transform:uppercase; color:var(--faint);}
  .mono{font-family:"Space Mono",monospace;}
  .num-idx{font-family:"Oswald",sans-serif; font-weight:400; font-size:12px; letter-spacing:0.24em; color:var(--faint);}
  .num-idx b{color:var(--fg); font-weight:500;}

  /* restrained reveal: a gentle fade+rise only. No word-by-word, no aggressive parallax. */
  .rise{opacity:0; transform:translateY(20px); transition:opacity 1.2s var(--ease), transform 1.2s var(--ease);}
  .rise.in{opacity:1; transform:none;}
  .rise.d1{transition-delay:.09s;} .rise.d2{transition-delay:.18s;} .rise.d3{transition-delay:.27s;}
  /* hairline that draws in — used on section separators for a crafted, subtle touch */
  .draw{transform:scaleX(0); transform-origin:left; transition:transform 1.3s var(--ease);}
  .draw.in{transform:scaleX(1);}
  /* image reveal: soft scale-settle behind a mask, very slow */
  .imgrise img{transform:scale(1.08); transition:transform 1.8s var(--ease), opacity 1.4s var(--ease); opacity:0;}
  .imgrise.in img{transform:scale(1); opacity:1;}

  /* ============ NAV ============ */
  header{position:fixed; top:0; left:0; right:0; z-index:100; display:flex; align-items:center; justify-content:space-between; padding:26px var(--edge); transition:padding .5s var(--ease), background .5s var(--ease), border-color .5s; border-bottom:1px solid transparent;}
  header.scrolled{padding:16px var(--edge); background:rgba(11,10,9,0.78); backdrop-filter:blur(16px); border-bottom:1px solid var(--hair);}
  header .logo{height:25px; width:auto; opacity:.95;}   /* 25px x 4.735 = 118px wide, the intended footprint */
  header nav{display:flex; gap:36px; align-items:center;}
  header nav a{font-family:"Oswald",sans-serif; font-size:12px; letter-spacing:0.16em; text-transform:uppercase; color:var(--dim); transition:color .3s;}
  header nav a:hover{color:var(--fg);}
  header .lang,
  header .sn-lang{font-family:"Oswald",sans-serif; font-size:11px; letter-spacing:0.12em; color:var(--faint);}
  /* Language switcher. Two short links separated by a hairline, in the same
     quiet register as the nav. The current language is legible but not a
     button: it is a state, not an action. */
  header .sn-lang{display:inline-flex; align-items:center; gap:9px;}
  header .sn-lang__item{color:var(--faint); transition:color .3s var(--ease);}
  header .sn-lang__item + .sn-lang__item{padding-left:9px; border-left:1px solid rgba(255,255,255,0.22);}
  header .sn-lang__item:hover{color:var(--fg);}
  header .sn-lang__item.is-current{color:var(--fg); cursor:default;}

  /* ============ 01 · HERO — full-bleed photograph, watch left, type in the void right ============ */
  .hero{position:relative; height:100vh; min-height:700px; overflow:hidden; display:flex; align-items:center;}
  /* the photograph fills the frame — it is already lit on black, so no mask, no bloom */
  .hero .himg{position:absolute; inset:0; z-index:1;
    background:url('../img/p-angle.webp') 32% 46%/cover no-repeat;
    will-change:transform;}
  /* scrim: darkens the right side so type reads, keeps the watch untouched on the left */
  .hero .hgrade{position:absolute; inset:0; z-index:2;
    background:linear-gradient(90deg, rgba(11,10,9,0.10) 0%, rgba(11,10,9,0.05) 34%, rgba(11,10,9,0.72) 62%, rgba(11,10,9,0.92) 100%),
               linear-gradient(180deg, rgba(11,10,9,0.55) 0%, transparent 26%, transparent 72%, rgba(11,10,9,0.85) 100%);}
  .hero .h-in{position:relative; z-index:3; margin-left:auto; width:min(46%,620px); padding-right:var(--edge); padding-left:20px;}
  .hero h1{font-weight:300; font-size:clamp(30px,3.6vw,52px); line-height:1.16; letter-spacing:-0.025em; color:#F7F5F0; text-shadow:0 6px 60px rgba(0,0,0,0.85);}
  .hero h1 em{font-style:italic; color:#fff;}
  .hero .cue{position:absolute; right:var(--edge); bottom:38px; z-index:3; display:flex; align-items:center; gap:12px;}
  /* 11px is the audit floor; 9px measured under it. Tracked uppercase reads
     larger than its px value, but the cue is raised rather than exempted. */
  .hero .cue span{font-family:"Oswald",sans-serif; font-size:11px; letter-spacing:0.32em; text-transform:uppercase; color:var(--faint);}
  .hero .cue .l{width:46px; height:1px; background:var(--faint);}
  @media (max-width:900px){
    .hero{align-items:flex-end;}
    .hero .himg{background-position:50% 38%;}
    .hero .hgrade{background:linear-gradient(180deg, rgba(11,10,9,0.5) 0%, transparent 30%, rgba(11,10,9,0.9) 78%, var(--black) 100%);}
    .hero .h-in{width:100%; margin-left:0; padding:0 var(--edge) 16vh;}
  }
  /* hero entrance states (toggled by .in) */
  /* Only the FIRST slide's headline takes the JS entrance. The others are
     driven by the slide keyframes; giving them opacity:0 here would leave
     slides 2 and 3 permanently invisible, since only slide 1 gets `.in`. */
  .js .hero .htext--1,.js .hero .cue{opacity:0; transform:translateY(16px); transition:opacity 1.2s var(--ease), transform 1.2s var(--ease);}
  .js .hero .htext--1.in,.js .hero .cue.in{opacity:1; transform:none;}

  /* section scaffold — generous silence */
  /* UX review (16 Sep), issue 05 + staging #7: 160px top AND bottom put 320px
     of dead space between every pair of sections, and several sections were
     only ~25% content. Trimmed to ~115px at this viewport — the brand's
     breathing room survives, the emptiness does not. */
  section.block{padding:clamp(88px,11.5vh,150px) 0;}
  .sechead{display:flex; align-items:center; gap:24px; margin-bottom:clamp(52px,7vh,96px);}
  .sechead .num-idx{white-space:nowrap;}
  .sechead .rule{flex:1; height:1px; background:var(--hair); transform-origin:left;}
  .sechead .label{white-space:nowrap;}

  /* UX review (16 Sep) — issue 01 site-wide, staging #3 and #6.
     In a FULL-BLEED band the section rule stretched edge to edge straight
     across the photograph, cutting through the watch case. The label and
     number still belong there (they carry the page's counting rhythm), but
     the rule does not: over a photograph it reads as a scratch on the print.
     On these bands the rule is dropped and the head is pushed off the image
     centre, so type and photograph stop competing. */


  /* ============ 02 · THE IDEA (calm statement) ============ */
  .idea .lead{font-weight:300; font-size:clamp(32px,4.4vw,68px); line-height:1.1; letter-spacing:-0.03em; max-width:16ch; color:#F1EFEA;}
  .idea .lead em{font-style:italic;}

  /* ============ 03 · TWO SYSTEMS, ONE OBJECT (the core idea) ============ */
  .duo .top{max-width:20ch; margin-bottom:70px;}
  .duo h2{font-weight:300; font-size:clamp(30px,4vw,60px); line-height:1.08; letter-spacing:-0.02em;}
  .duo .cols{display:grid; grid-template-columns:1fr 1fr; gap:1px; background:var(--hair); border:1px solid var(--hair);}
  .duo .cell{position:relative; background:var(--black); padding:clamp(38px,4vw,68px); transition:background .6s var(--ease);}
  .duo .cell:hover{background:var(--panel);}
  .duo .cell .k{font-family:"Oswald",sans-serif; font-size:12px; letter-spacing:0.22em; text-transform:uppercase; color:var(--faint); margin-bottom:28px; display:flex; align-items:center; gap:12px;}
  .duo .cell .k::before{content:""; width:20px; height:1px; background:var(--dim);}
  .duo .cell h3{font-weight:400; font-size:clamp(22px,2.2vw,30px); line-height:1.14; letter-spacing:-0.015em; margin-bottom:18px;}
  .duo .cell p{font-size:15.5px; line-height:1.8; color:var(--dim); max-width:34ch;}
  .duo .foot{margin-top:48px; text-align:center;}
  .duo .foot p{font-weight:300; font-size:clamp(18px,2vw,26px); color:#E9E7E1; letter-spacing:-0.01em;}
  .duo .foot em{font-style:italic;}

  /* ============ 04 · PRIVACY — full-bleed, emotional entry ============ */
  .privacy{position:relative; height:100vh; min-height:640px; overflow:hidden; display:flex; align-items:center;}
  .privacy .pimg{position:absolute; inset:0; z-index:0; background:url('../img/privacy-wrist.webp') center 40%/cover no-repeat;}
  .privacy .shade{position:absolute; inset:0; z-index:1; background:linear-gradient(90deg, rgba(11,10,9,0.9) 20%, rgba(11,10,9,0.35) 58%, transparent), linear-gradient(180deg, rgba(11,10,9,0.6), transparent 34%, rgba(11,10,9,0.7));}
  .privacy .p-in{position:relative; z-index:2; max-width:44ch;}
  .privacy .label{color:#B9BEC0; margin-bottom:28px; display:block;}
  .privacy h2{font-weight:300; font-size:clamp(38px,6vw,88px); line-height:1.0; letter-spacing:-0.025em; text-shadow:0 6px 60px rgba(0,0,0,0.7);}
  .privacy p{margin-top:32px; max-width:40ch; font-size:17px; line-height:1.7; color:#DAD8D2;}

  /* ============ 05 · CRAFT — individual image-led rows, alternating ============ */
  .craft .lead{font-weight:300; font-size:clamp(28px,3.6vw,52px); line-height:1.14; letter-spacing:-0.02em; max-width:18ch; margin-bottom:clamp(70px,10vh,140px);}
  .craft-row{display:grid; grid-template-columns:1.05fr 0.95fr; align-items:center; gap:clamp(40px,7vw,120px); margin-bottom:clamp(90px,13vh,180px);}
  .craft-row:last-child{margin-bottom:0;}
  .craft-row.rev .cr-fig{order:2;} .craft-row.rev .cr-txt{order:1;}
  /* The photographs are transparent cutouts lit on black, so the container
     needs NO fill of its own — `background:#000` was drawing the hard-edged
     rectangle the client reported, a visible box floating on the page.
     `cover` was also cropping the watch (up to 17% of the width on the 5:4
     rows), so it becomes `contain`: the object sits whole inside the frame. */
  .cr-fig{position:relative; aspect-ratio:4/5; overflow:hidden; background:none;}
  .cr-fig img{width:100%; height:100%; object-fit:contain;}
  .craft-row.wide .cr-fig{aspect-ratio:5/4;}
  .cr-txt .idx{font-family:"Space Mono",monospace; font-size:12px; letter-spacing:0.1em; color:var(--faint); margin-bottom:24px;}
  .cr-txt h3{font-family:"Oswald",sans-serif; font-weight:300; font-size:clamp(30px,3.4vw,52px); line-height:1.02; letter-spacing:-0.02em; margin-bottom:24px;}
  .cr-txt p{font-size:16.5px; line-height:1.8; color:var(--dim); max-width:34ch;}
  .cr-txt .kbd{margin-top:28px; font-family:"Oswald",sans-serif; font-size:11px; letter-spacing:0.24em; text-transform:uppercase; color:var(--faint); display:flex; align-items:center; gap:12px;}
  .cr-txt .kbd::before{content:""; width:24px; height:1px; background:var(--dim);}

  /* ============ 06 · THE COLOSSAL MOMENT — text-free, luminous ============ */
  .moment{position:relative; height:118vh; min-height:820px; overflow:hidden; background:#000;}
  .moment .mimg{position:absolute; inset:0; background:url('../img/p-front-ti.webp') center 46%/cover no-repeat; will-change:transform;}
  .moment::after{content:""; position:absolute; inset:0; background:radial-gradient(ellipse 76% 76% at 50% 48%, transparent 58%, rgba(11,10,9,0.7) 100%), linear-gradient(180deg, var(--black), transparent 14%, transparent 86%, var(--black));}

  /* ============ 07 · SPECIFICATION — Opt 1/4 technical drawing, warm-light section ============ */
  .spec{background:var(--paper); color:var(--ink);}
  .spec .sechead .num-idx{color:var(--paper-dim);} .spec .sechead .num-idx b{color:var(--ink);}
  .spec .sechead .label{color:var(--paper-dim);} .spec .sechead .rule{background:rgba(26,24,21,0.14);}
  /* the plate is inset so the leader-lines land on the paper, never on the photograph */
  .spec .drawing{position:relative; display:flex; justify-content:center; padding:0 clamp(120px,18vw,260px);}
  .spec .plate{position:relative; width:min(640px,100%); aspect-ratio:3/2;}
  /* UX review (16 Sep), staging doc #4: this section sits on CREAM and the
     photograph carried a solid black plate, so a hard black rectangle floated
     on a light ground — the most jarring instance on the site. The image is
     now a transparent cutout, so:
       - no `background` at all: the paper shows through;
       - `contain`, not `cover`: `cover` was also cropping through the case
         (staging doc #10). */
  .spec .plate img{width:100%; height:100%; object-fit:contain; background:none;}
  .spec .anno{position:absolute; font-family:"Space Mono",monospace; font-size:12px; letter-spacing:0.03em; color:var(--ink); white-space:nowrap;}
  .spec .anno::before{content:""; position:absolute; background:rgba(26,24,21,0.45);}
  /* annotations sit OUTSIDE the plate on the paper; leader-lines reach in to the edge */
  .spec .anno{transform:translateY(-50%);}
  .spec .a1{top:20%; right:calc(100% + 68px); text-align:right;} .spec .a1::before{width:56px; height:1px; top:50%; left:calc(100% + 6px);}
  .spec .a2{top:50%; right:calc(100% + 68px); text-align:right;} .spec .a2::before{width:56px; height:1px; top:50%; left:calc(100% + 6px);}
  .spec .a3{top:80%; right:calc(100% + 68px); text-align:right;} .spec .a3::before{width:56px; height:1px; top:50%; left:calc(100% + 6px);}
  .spec .a4{top:20%; left:calc(100% + 68px);} .spec .a4::before{width:56px; height:1px; top:50%; right:calc(100% + 6px);}
  .spec .a5{top:50%; left:calc(100% + 68px);} .spec .a5::before{width:56px; height:1px; top:50%; right:calc(100% + 6px);}
  .spec .a6{top:80%; left:calc(100% + 68px);} .spec .a6::before{width:56px; height:1px; top:50%; right:calc(100% + 6px);}
  @media (max-width:900px){
    .spec .drawing{padding:0;}
    .spec .anno{position:static; transform:none; display:flex; justify-content:space-between; padding:14px 0; border-top:1px solid rgba(26,24,21,0.14);}
    .spec .anno::before{display:none;}
    .spec .plate{aspect-ratio:16/10;}
  }
  .spec .caption{text-align:center; margin-top:64px; font-family:"Space Mono",monospace; font-size:12px; letter-spacing:0.06em; color:var(--paper-dim);}

  /* ============ 08 · THE ANSWER — SN 2140 named ============ */
  .answer{text-align:center;}
  .answer .watch{position:relative; width:min(520px,60vw); margin:0 auto 54px;
    -webkit-mask-image:radial-gradient(ellipse 74% 72% at 50% 50%, #000 56%, transparent 82%);
            mask-image:radial-gradient(ellipse 74% 72% at 50% 50%, #000 56%, transparent 82%);}
  .answer .watch img{width:100%; filter:brightness(1.12) contrast(1.03);}
  .answer .label{display:block; margin-bottom:28px;}
  .answer h2{font-weight:300; font-size:clamp(32px,4.4vw,66px); line-height:1.04; letter-spacing:-0.025em; max-width:18ch; margin:0 auto 30px;}
  .answer .q{font-weight:300; font-size:clamp(18px,1.9vw,25px); color:var(--dim); max-width:32ch; margin:0 auto 46px; line-height:1.5;}
  .answer .link{font-family:"Oswald",sans-serif; font-size:12px; letter-spacing:0.2em; text-transform:uppercase; position:relative; padding-bottom:9px;}
  .answer .link::after{content:""; position:absolute; left:0; bottom:0; width:100%; height:1px; background:var(--fg); transform:scaleX(0); transform-origin:left; transition:transform .55s var(--ease);}
  .answer .link:hover::after{transform:scaleX(1);}
  .answer .link .a{margin-left:8px; display:inline-block; transition:transform .5s var(--ease);}
  .answer .link:hover .a{transform:translateX(7px);}

  /* ============ 09 · THE FOUNDERS — moved LATE, short, 1–2 photos ============ */
  .founders .cols{display:grid; grid-template-columns:0.9fr 1.1fr; gap:80px; align-items:center;}
  .founders figure{position:relative; aspect-ratio:4/5; overflow:hidden; background:#000;}
  .founders figure img{width:100%; height:100%; object-fit:cover; object-position:center 52%;}
  .founders h2{font-weight:300; font-size:clamp(28px,3.4vw,48px); line-height:1.06; letter-spacing:-0.02em; max-width:14ch; margin-bottom:36px;}
  .founders .names{display:flex; flex-direction:column; gap:32px;}
  .founders .names h4{font-family:"Oswald",sans-serif; font-weight:400; font-size:15px; letter-spacing:0.06em; text-transform:uppercase; margin-bottom:12px; color:var(--fg);}
  .founders .names p{font-size:15.5px; line-height:1.75; color:var(--dim); max-width:40ch;}
  .founders .place{margin-top:40px; font-family:"Space Mono",monospace; font-size:12px; color:var(--faint);}

  /* ============ 10 · FINITE / RESERVE ============ */
  .finite{text-align:center;}
  .finite h2{font-weight:300; font-size:clamp(36px,5.5vw,88px); line-height:0.98; letter-spacing:-0.025em; margin-bottom:34px;}
  .finite .sub{max-width:44ch; margin:0 auto; font-size:16px; line-height:1.8; color:var(--dim);}
  .finite .stat{display:flex; justify-content:center; gap:clamp(40px,6vw,80px); flex-wrap:wrap; margin:64px 0 0;}
  .finite .stat .n{font-weight:300; font-size:clamp(26px,3vw,42px); letter-spacing:-0.01em;}
  .finite .stat .k{font-family:"Oswald",sans-serif; font-size:11px; letter-spacing:0.2em; text-transform:uppercase; color:var(--faint); margin-top:12px;}
  .finite .cta{display:inline-block; margin-top:66px; font-family:"Oswald",sans-serif; font-size:12px; letter-spacing:0.22em; text-transform:uppercase; border:1px solid rgba(255,255,255,0.42); padding:22px 60px; transition:background .5s var(--ease), color .5s var(--ease);}
  .finite .cta:hover{background:var(--fg); color:var(--black);}
  .finite .note{margin-top:26px; font-size:12.5px; color:var(--faint);}

  /* ============ FOOTER ============ */
  footer{padding:100px 0 56px; border-top:1px solid var(--hair); background:#080706;}
  .fgrid{display:grid; grid-template-columns:1.6fr 1fr 1fr 1.2fr; gap:52px; align-items:start;}
  .fbrand img{width:auto; height:24px; opacity:.7; margin-bottom:22px;}
  .fbrand p{font-size:12.5px; color:var(--faint); line-height:1.8; max-width:250px;}
  .fbrand .swiss{margin-top:16px; font-family:"Space Mono",monospace; font-size:11px; color:var(--dim); line-height:1.9;}
  .fcol h6,.fcol .fh{font-family:"Oswald",sans-serif; font-size:10px; letter-spacing:0.2em; text-transform:uppercase; color:var(--faint); margin-bottom:18px; font-weight:400;}
  /* Footer column labels were <h6>; now <p class="fh"> (they label link lists,
     they are not headings, and h6 after the page's h2s broke the outline).
     Pinned to the old h6 metrics so `.fnl p` cannot restyle "Stay Close". */
  .fcol .fh,.fnl .fh{line-height:1.5; margin-top:0; max-width:none;}
  .fcol ul{list-style:none;} .fcol li{margin-bottom:11px;}
  .fcol a{font-size:12.5px; color:#807a71; transition:color .3s;}
  .fcol a:hover{color:var(--dim);}
  .fnl p{font-size:12px; color:var(--faint); line-height:1.75; margin-bottom:16px; max-width:240px;}
  .fnl .field{display:flex; align-items:center; border-bottom:1px solid rgba(255,255,255,0.14); padding-bottom:10px; max-width:250px;}
  .fnl input{flex:1; background:none; border:none; outline:none; color:var(--dim); font-family:inherit; font-size:12.5px;}
  .fnl input::placeholder{color:var(--faint);}
  .fnl button{background:none; border:none; color:#807a71; cursor:pointer; font-size:15px;}
  /* The wrapper must fill its grid cell: `.fnl .field` is capped at 250px, and
     without this the notice inherits a narrow measure and sets as a ragged
     column beside the input instead of a line beneath it. */
  .sn-newsletter-wrap{width:100%;}

  /* Newsletter result. 12px is the floor for legibility (responsive audit);
     the message is quiet but must never be unreadable. The width is stated
     here because `.fnl p` above caps every paragraph in this column at 240px,
     which is narrower than the text needs. */
  .sn-newsletter__notice{display:block; margin:12px 0 0; max-width:min(32ch,100%); font-size:12px; line-height:1.6; letter-spacing:0.01em;}
  .sn-newsletter__notice--ok{color:var(--dim);}
  .sn-newsletter__notice--error{color:#c77b6a;}

  .fbot{display:flex; justify-content:space-between; margin-top:64px; padding-top:26px; border-top:1px solid var(--hair);}
  .fbot span{font-family:"Space Mono",monospace; font-size:11px; color:var(--faint);}

  @media (max-width:900px){
    .idea .body,.duo .cols,.founders .cols{grid-template-columns:1fr; gap:32px;}
    .craft-row{grid-template-columns:1fr; gap:32px; margin-bottom:80px;}
    .craft-row.rev .cr-fig{order:1;} .craft-row.rev .cr-txt{order:2;}
    .cr-fig,.craft-row.wide .cr-fig{aspect-ratio:16/10;}
    .fgrid{grid-template-columns:1fr 1fr; gap:40px;}
  }
  @media (max-width:560px){
    .fgrid{grid-template-columns:1fr;}
    .hero h1{font-size:22px;}
  }
  /* ============ JOURNAL — News/Media Hub index ============
     Extracted verbatim from the approved journal.html. These classes were
     missing from this file, which left the Journal Grid widget unstyled. */
  .jhead{padding:clamp(130px,18vh,200px) 0 clamp(44px,6vh,78px);}
  .jhead .label{display:block; margin-bottom:30px;}
  .jhead h1{font-weight:300; font-size:clamp(38px,6vw,92px); line-height:0.98; letter-spacing:-0.03em;}
  .jhead p{margin-top:32px; max-width:44ch; font-size:17px; line-height:1.7; color:var(--dim);}

  /* FEATURED — first card large */
  .feat{border-top:1px solid var(--hair); padding-top:clamp(48px,7vh,90px);}
  .feat a{display:grid; grid-template-columns:1.15fr 1fr; gap:clamp(40px,6vw,90px); align-items:center;}
  .feat .fig{position:relative; aspect-ratio:5/4; overflow:hidden; background:#000;}
  .feat .fig img{width:100%; height:100%; object-fit:cover; transition:transform 1.4s var(--ease);}
  .feat a:hover .fig img{transform:scale(1.04);}
  .feat .meta{display:flex; gap:18px; align-items:center; margin-bottom:26px; font-family:"Oswald",sans-serif; font-size:11px; letter-spacing:0.2em; text-transform:uppercase; color:var(--faint);}
  .feat .meta .cat{color:var(--dim);}
  .feat .meta .dot{width:3px; height:3px; border-radius:50%; background:var(--faint);}
  .feat h2{font-weight:300; font-size:clamp(26px,3.2vw,46px); line-height:1.08; letter-spacing:-0.02em; margin-bottom:24px;}
  .feat .ex{font-size:16.5px; line-height:1.8; color:var(--dim); max-width:40ch; margin-bottom:30px;}
  .feat .more{font-family:"Oswald",sans-serif; font-size:12px; letter-spacing:0.2em; text-transform:uppercase; color:var(--dim); display:inline-flex; align-items:center; gap:10px;}
  .feat .more .a{transition:transform .5s var(--ease);}
  .feat a:hover .more{color:var(--fg);}
  .feat a:hover .more .a{transform:translateX(7px);}

  /* GRID of the rest */
  /* Column count follows the number of articles (see index.php), so two posts
     fill the row instead of leaving a third cell empty. Capped at three. */
  /* Staging review #9: on mobile the gap between the Journal intro and the
     first article image read as a dead band. .jhead already contributes up to
     110px of bottom padding, so 170px on top of it was ~280px of nothing. */
  .jgrid{margin-top:clamp(48px,7vh,92px); display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--hair); border-top:1px solid var(--hair); border-bottom:1px solid var(--hair);}
  .jgrid--1{grid-template-columns:minmax(0,640px);}
  .jgrid--2{grid-template-columns:repeat(2,1fr);}
  .jgrid--3{grid-template-columns:repeat(3,1fr);}
  .jcard{background:var(--black); padding:0;}
  .jcard a{display:block; padding:0;}
  .jcard .fig{position:relative; aspect-ratio:4/3; overflow:hidden; background:#000;}
  .jcard .fig img{width:100%; height:100%; object-fit:cover; transition:transform 1.4s var(--ease);}
  .jcard a:hover .fig img{transform:scale(1.05);}
  .jcard .txt{padding:clamp(28px,2.4vw,40px);}
  .jcard .meta{display:flex; gap:14px; align-items:center; margin-bottom:20px; font-family:"Oswald",sans-serif; font-size:10px; letter-spacing:0.2em; text-transform:uppercase; color:var(--faint);}
  .jcard .meta .cat{color:var(--dim);}
  .jcard .meta .dot{width:3px; height:3px; border-radius:50%; background:var(--faint);}
  .jcard h3{font-weight:400; font-size:clamp(19px,1.9vw,24px); line-height:1.16; letter-spacing:-0.015em; margin-bottom:16px;}
  .jcard p{font-size:14.5px; line-height:1.75; color:var(--dim);}

  @media (max-width:900px){
    .feat a{grid-template-columns:1fr; gap:32px;}
    .jgrid{grid-template-columns:1fr;}
  }

  @media (prefers-reduced-motion:reduce){html{scroll-behavior:auto;} *{animation:none!important; transition:none!important;} .rise{opacity:1; transform:none;}}

/* ---------------------------------------------------------------
 * Contact form
 *
 * Same hairline-underline language as the checkout fields, so the two
 * forms on the site feel like one system. Inputs are transparent with a
 * single rule beneath; focus brightens the rule rather than drawing a box.
 * -------------------------------------------------------------- */
.sn-form-wrap{max-width:760px;}

.sn-form__grid{display:grid; grid-template-columns:1fr 1fr; gap:0 clamp(24px,3vw,44px);}
@media (max-width:640px){.sn-form__grid{grid-template-columns:1fr;}}
.sn-field--wide{grid-column:1 / -1;}

.sn-field{position:relative; margin:0 0 clamp(28px,3.4vh,38px);}
.sn-field label{
  display:block; margin-bottom:11px;
  font-family:"Oswald",sans-serif; font-weight:400; font-size:10px;
  letter-spacing:0.22em; text-transform:uppercase; color:var(--faint);
}
.sn-field input[type="text"],
.sn-field input[type="email"],
.sn-field textarea,
.sn-field select{
  width:100%; display:block;
  background:transparent; color:var(--fg);
  border:none; border-bottom:1px solid var(--hair); border-radius:0;
  padding:0 0 13px; font-family:inherit; font-size:15px; line-height:1.5;
  -webkit-appearance:none; appearance:none;
  transition:border-color .45s var(--ease);
}
.sn-field textarea{min-height:132px; resize:vertical; line-height:1.75;}
.sn-field input:focus,
.sn-field textarea:focus,
.sn-field select:focus{outline:none; border-bottom-color:rgba(255,255,255,0.55);}
.sn-field input:-webkit-autofill,
.sn-field textarea:-webkit-autofill{
  -webkit-text-fill-color:var(--fg);
  -webkit-box-shadow:0 0 0 1000px var(--black) inset;
  transition:background-color 9999s ease-out;
}

/* select needs its own arrow once the native one is removed */
.sn-select{position:relative; display:block;}
.sn-select::after{
  content:""; position:absolute; right:2px; top:50%; width:7px; height:7px;
  margin-top:-9px; border-right:1px solid var(--faint); border-bottom:1px solid var(--faint);
  transform:rotate(45deg); pointer-events:none;
}
.sn-field select option{background:var(--black); color:var(--fg);}

/* validation */
.sn-field.has-error input,
.sn-field.has-error textarea{border-bottom-color:#B4675A;}
.sn-field__err{
  display:block; margin-top:9px; font-size:12px; line-height:1.5; color:#C0796B;
}

/* honeypot — hidden from people, reachable by bots. Not display:none. */
.sn-hp{position:absolute; left:-9999px; top:auto; width:1px; height:1px; overflow:hidden;}

.sn-form__foot{
  display:flex; align-items:center; gap:clamp(20px,3vw,38px); flex-wrap:wrap;
  margin-top:clamp(12px,2vh,22px);
}
.sn-form__priv{font-size:12px; line-height:1.6; color:var(--faint); max-width:34ch;}

/* solid variant of the CTA, for the primary action on a form */
.sn-cta--solid{background:var(--fg); color:var(--black); border-color:var(--fg);}
.sn-cta--solid:hover{background:transparent; color:var(--fg); border-color:rgba(255,255,255,0.42);}

/* result notices */
.sn-form-note{
  border:1px solid var(--hair); padding:clamp(20px,2.4vw,28px);
  margin-bottom:clamp(30px,4vh,46px); background:rgba(255,255,255,0.02);
}
.sn-form-note .label{display:block; margin-bottom:10px;}
.sn-form-note p{margin:0; font-size:15px; line-height:1.75; color:var(--dim);}
.sn-form-note--ok{border-left:1px solid var(--blue);}
.sn-form-note--err{border-left:1px solid #B4675A;}
.sn-form-note--err p{color:#C0796B;}

/* contact section — the form sits inside the page's editorial rhythm */
.sn-contact__intro{
  font-size:clamp(15px,1.5vw,17px); line-height:1.8; color:var(--dim);
  max-width:56ch; margin:0 0 clamp(38px,5vh,60px);
}
.sn-contact__form{margin-top:clamp(10px,2vh,20px);}

/* ---------------------------------------------------------------
 * Homepage visual configurator
 *
 * A viewer, not a second checkout: the stage is generous, the controls
 * are quiet, and the only strong element is the pre-order CTA. Strap is
 * presentation only — both ship with the watch — so its group carries a
 * hint line saying exactly that.
 * -------------------------------------------------------------- */
.sn-cfg{
  display:grid; grid-template-columns:1.25fr 0.75fr;
  gap:clamp(30px,5vw,80px); align-items:center;
  margin-top:clamp(36px,5vh,64px);
}
@media (max-width:900px){.sn-cfg{grid-template-columns:1fr; gap:40px;}}

.sn-cfg__stage{
  /* No fill and no border: the photograph is already lit on black, so the box
     only drew a visible rectangle on the page — the same fault reported on the
     craft rows and the Specification plate. */
  position:relative; background:none;
  border:0; overflow:hidden;
  aspect-ratio:3/4; display:flex; align-items:center; justify-content:center;
}
.sn-cfg__img{
  width:100%; height:100%; object-fit:contain; display:block;
  transition:opacity .28s var(--ease);
}
.sn-cfg__note{
  position:absolute; left:0; right:0; bottom:0; margin:0;
  padding:14px 18px; background:rgba(11,10,9,0.9);
  border-top:1px solid var(--hair);
  font-size:11.5px; line-height:1.6; color:var(--dim);
}

.sn-cfg__panel{display:flex; flex-direction:column; gap:clamp(24px,3.4vh,38px);}
.sn-cfg__legend{display:block; margin-bottom:14px;}

.sn-cfg__opts{display:flex; flex-wrap:wrap; gap:10px;}
.sn-cfg__opt{
  display:inline-flex; align-items:center; gap:10px;
  background:none; border:1px solid var(--hair); border-radius:0;
  padding:11px 16px; cursor:pointer; color:var(--dim);
  font-family:inherit; font-size:13px; line-height:1;
  transition:border-color .4s var(--ease), color .4s var(--ease);
  -webkit-appearance:none; appearance:none;
}
.sn-cfg__opt:hover{border-color:rgba(255,255,255,0.34); color:var(--fg);}
.sn-cfg__opt:focus-visible{outline:1px solid var(--blue); outline-offset:2px;}
.sn-cfg__opt.is-active{border-color:rgba(255,255,255,0.6); color:var(--fg);}

/* colour chips: the actual finishes, not decorative dots */
.sn-cfg__sw{width:13px; height:13px; border-radius:50%; display:inline-block; flex:none;}
.sn-cfg__sw--natural-titanium{background:linear-gradient(135deg,#cfcbc4,#8d8981);}
.sn-cfg__sw--anthracite-pvd{background:linear-gradient(135deg,#3a3936,#141312);}
.sn-cfg__sw--light-gray{background:linear-gradient(135deg,#b8b4ad,#8e8a83);}
.sn-cfg__sw--dark-anthracite{background:linear-gradient(135deg,#2e2d2b,#111);}

.sn-cfg__hint{
  margin:12px 0 0; font-size:11.5px; line-height:1.6; color:var(--faint); max-width:34ch;
}

.sn-cfg__foot{
  display:flex; flex-direction:column; align-items:flex-start; gap:14px;
  padding-top:clamp(12px,2vh,20px); border-top:1px solid var(--hair);
}
.sn-cfg__cta{text-align:center;}
.sn-cfg__meta{font-size:11px; letter-spacing:0.04em; color:var(--faint);}

/* ---------------------------------------------------------------
 * Film
 *
 * Poster-first: nothing loads until asked. Framed like the other
 * figures on the site — hairline border, black ground, no chrome of
 * its own beyond the native controls.
 * -------------------------------------------------------------- */
.sn-film__frame{
  margin:clamp(34px,5vh,60px) 0 0; padding:0;
  border:1px solid var(--hair); background:#000; overflow:hidden;
  aspect-ratio:16/9;
}
.sn-film__video,
.sn-film__still{width:100%; height:100%; object-fit:cover; display:block;}
.sn-film__cap{
  display:block; margin-top:16px; font-size:11px;
  letter-spacing:0.06em; color:var(--faint);
}

/* A case with only one dial has no choice to present: the row steps back to
   a statement rather than showing a lone selectable "option". */
.sn-cfg__group.is-single .sn-cfg__opt{
  border-color:transparent; padding-left:0; cursor:default; color:var(--dim);
}
.sn-cfg__group.is-single .sn-cfg__opt:hover{border-color:transparent;}

/* ---------------------------------------------------------------
 * Press room (restricted)
 * -------------------------------------------------------------- */
.sn-gate{max-width:52ch; padding:clamp(60px,12vh,140px) 0;}
.sn-gate__label{display:block; margin-bottom:24px;}
.sn-gate__head{
  font-weight:300; font-size:clamp(30px,4vw,54px); line-height:1.06;
  letter-spacing:-0.025em; margin:0 0 22px;
}
.sn-gate__body{font-size:16px; line-height:1.8; color:var(--dim); margin:0 0 38px;}
.sn-gate__form{display:flex; gap:14px; flex-wrap:wrap; align-items:stretch;}
.sn-gate__form input[type="password"]{
  flex:1 1 220px; background:transparent; color:var(--fg);
  border:none; border-bottom:1px solid var(--hair); border-radius:0;
  padding:0 0 13px; font-family:inherit; font-size:15px;
  -webkit-appearance:none; appearance:none;
}
.sn-gate__form input[type="password"]:focus{outline:none; border-bottom-color:rgba(255,255,255,0.55);}
.sn-gate__foot{margin:34px 0 0; font-size:13px; color:var(--faint);}
.sn-gate__foot a{color:var(--dim); text-decoration:none; border-bottom:1px solid var(--hair);}

.sn-press__group{margin:0 0 clamp(50px,7vh,86px);}
.sn-press__list{list-style:none; margin:clamp(22px,3vh,32px) 0 0; padding:0;}
.sn-press__item{
  display:grid; grid-template-columns:1fr auto auto; gap:20px;
  align-items:baseline; padding:18px 0; border-bottom:1px solid var(--hair);
}
@media (max-width:640px){
  .sn-press__item{grid-template-columns:1fr auto; }
  .sn-press__meta{grid-column:1 / -1; order:3;}
}
.sn-press__name{font-size:15px; line-height:1.5; color:var(--fg);}
.sn-press__meta{font-size:11px; letter-spacing:0.06em; color:var(--faint); white-space:nowrap;}
.sn-press__dl{
  font-family:"Oswald",sans-serif; font-size:10px; letter-spacing:0.2em;
  text-transform:uppercase; color:var(--fg); text-decoration:none;
  border-bottom:1px solid rgba(255,255,255,0.4); padding-bottom:3px; white-space:nowrap;
  transition:border-color .4s var(--ease);
}
.sn-press__dl:hover{border-bottom-color:var(--fg);}
.sn-press__dl--pending{color:var(--faint); border-bottom-style:dashed; border-bottom-color:var(--hair);}
.sn-press__item.is-pending .sn-press__name{color:var(--dim);}
.sn-press__body{font-size:15px; line-height:1.8; color:var(--dim); margin:20px 0 0; max-width:56ch;}
.sn-press__body a{color:var(--fg); text-decoration:none; border-bottom:1px solid var(--hair);}

/* ---------------------------------------------------------------
 * Hero — brand presence and the offer, above the fold
 *
 * The hero was a photograph with one sentence on it: no mark, no
 * reference, no price, nothing to act on. These three additions fix
 * that without adding noise — a hairline strip at the top, and a
 * button + meta line under the headline.
 * -------------------------------------------------------------- */
.hero .h-top{
  position:absolute; top:0; left:0; right:0; z-index:3;
  display:flex; align-items:center; gap:20px;
  padding:calc(var(--edge) * 0.42) var(--edge) 0;
}
.hero .h-top .label{color:rgba(255,255,255,0.62); white-space:nowrap;}
.hero .h-top__rule{flex:1; height:1px; background:rgba(255,255,255,0.14);}
@media (max-width:760px){
  .hero .h-top{padding-top:22px; gap:12px;}
  .hero .h-top .label{font-size:9px; letter-spacing:0.24em;}
}

.hero .h-meta{
  display:flex; flex-direction:column; align-items:flex-start; gap:18px;
  margin-top:clamp(30px,4vh,46px);
}
/* Set on its own line and allowed to breathe: as a single run it wrapped
   mid-phrase ("...December / 2026"), which reads like a mistake. */
.hero .h-meta__line{
  font-size:11px; line-height:1.9; letter-spacing:0.04em;
  color:rgba(255,255,255,0.58); text-shadow:0 2px 24px rgba(0,0,0,0.9);
  max-width:38ch;
}
@media (max-width:760px){
  .hero .h-meta{gap:14px; margin-top:24px;}
  .hero .h-meta .sn-cta{padding:16px 34px; font-size:11px;}
}
/* The meta block shares the hero's staged entrance. */
.js .hero .h-meta{opacity:0; transform:translateY(16px); transition:opacity 1.2s var(--ease), transform 1.2s var(--ease);}
.js .hero .h-meta.in{opacity:1; transform:none;}

/* ---------------------------------------------------------------
 * Configurator — give it the weight of a product display
 *
 * It was floating on the page background with no edge, which made the
 * most important section on the homepage read as the least finished.
 * -------------------------------------------------------------- */
.sn-configure{
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,0.035) 0%, transparent 62%),
    var(--black);
}
.sn-cfg{
  border:1px solid var(--hair);
  background:linear-gradient(180deg, rgba(255,255,255,0.02), transparent 55%);
  padding:clamp(22px,3vw,46px);
  gap:clamp(26px,4vw,64px);
}
.sn-cfg__stage{
  border:none; background:transparent;
  aspect-ratio:1/1;
}
.sn-cfg__stage::after{
  /* a soft pool of light under the watch, per the Charte's clair-obscur */
  content:""; position:absolute; left:50%; bottom:6%; transform:translateX(-50%);
  width:62%; height:16%; border-radius:50%;
  background:radial-gradient(ellipse at center, rgba(255,255,255,0.09), transparent 70%);
  pointer-events:none; z-index:0;
}
.sn-cfg__img{position:relative; z-index:1;}
.sn-cfg__panel{gap:clamp(20px,2.8vh,32px);}

/* On the homepage the craft band is a breath between choosing and
   committing, not a destination in itself — so it runs shorter than the
   full-height version used on the SN 2140 page. */
.home .moment{height:76vh; min-height:520px;}
@media (max-width:760px){.home .moment{height:56vh; min-height:380px;}}

/* ---------------------------------------------------------------
 * Hero, retuned for the 2026 wrist photography.
 *
 * The portrait wrist shot is a dark subject on a dark ground, framed
 * loosely. Straight `cover` at 100vh left the watch small in a large
 * black field, and the original scrim (built for a left-weighted product
 * render) darkened it further. Three corrections: scale into the frame so
 * the watch reads, lift the midtones, and darken only the right side
 * where the type actually sits.
 * -------------------------------------------------------------- */
.home .hero .himg{
  background-position:44% 30%;
  background-size:132% auto;
  filter:brightness(1.28) contrast(1.04);
}
.home .hero .hgrade{
  background:
    /* Stronger, and it begins further left: the type column starts around 54%,
       and each slide frames the watch differently, so the ramp has to be dark
       enough by then for ANY of the three photographs. */
    linear-gradient(90deg,
      rgba(11,10,9,0.34) 0%,
      rgba(11,10,9,0.00) 20%,
      rgba(11,10,9,0.10) 38%,
      rgba(11,10,9,0.58) 54%,
      rgba(11,10,9,0.88) 72%,
      rgba(11,10,9,0.96) 100%),
    linear-gradient(180deg,
      rgba(11,10,9,0.70) 0%,
      transparent 22%,
      transparent 62%,
      rgba(11,10,9,0.86) 90%,
      var(--black) 100%);
}
@media (max-width:900px){
  .home .hero .himg{background-position:50% 26%; background-size:150% auto;}
  .home .hero .hgrade{
    background:linear-gradient(180deg, rgba(11,10,9,0.60) 0%, transparent 24%, rgba(11,10,9,0.90) 70%, var(--black) 100%);
  }
}

/* The type column sits slightly above centre: with the CTA and meta line
   added it was bottom-weighted, leaving a dead band under the fold. */
.home .hero{align-items:center;}
.home .hero .h-in{transform:translateY(-4vh);}
@media (max-width:900px){.home .hero .h-in{transform:none;}}

/* Mobile stacking, re-declared LAST.
   The polish block above re-sets `gap` on .sn-cfg, which came after the
   original max-width:900px rule and silently defeated its gap. Ordering
   matters here — keep this the final word on the configurator grid. */
@media (max-width:900px){
  .sn-cfg{grid-template-columns:1fr; gap:36px; padding:clamp(18px,4vw,28px);}
  /* 3/4 matches the source art (1200x1600). At 4/5 the stage was TALLER than
     the photograph, so object-fit:contain letterboxed it and the watch read as
     cropped and small on a phone. */
  .sn-cfg__stage{aspect-ratio:3/4;}
}

/* ---------------------------------------------------------------
 * Statement section (03 · The House)
 *
 * `.idea .body` previously had NO rules at all — only a grid override
 * inside a max-width:900px media query, which never applied on desktop.
 * So the paragraph ran the full 1360px measure and sat flush against the
 * headline: no separation, unreadable line length, exactly the "spacing
 * feels off" note. It needs a measure, a rhythm and space above.
 * -------------------------------------------------------------- */
.idea .lead{margin-bottom:clamp(28px,4vh,52px);}
.idea .body{
  max-width:62ch;
  font-size:clamp(15px,1.35vw,17px);
  line-height:1.85;
  color:var(--dim);
  margin:0;
}
/* The headline sets its own measure; on wide screens 16ch is very narrow for
   a three-line sentence, so let it breathe a little further. */
.idea .lead{max-width:22ch;}
@media (max-width:900px){
  .idea .lead{max-width:18ch;}
  .idea .body{max-width:100%; font-size:15px;}
}

/* ---------------------------------------------------------------
 * Closing CTA — the last thing before the footer.
 *
 * It now ends the page rather than sitting mid-scroll, so it carries a
 * little more weight: a faint pool of light behind it and a hairline
 * above, without becoming a loud "buy now" panel.
 * -------------------------------------------------------------- */
.finite{
  position:relative;
  border-top:1px solid var(--hair);
  background:radial-gradient(120% 100% at 50% 100%, rgba(255,255,255,0.045) 0%, transparent 60%), var(--black);
}
.finite .stat{border-top:1px solid var(--hair); padding-top:clamp(38px,5vh,58px);}
.finite .cta{margin-top:clamp(46px,6vh,66px);}

/* ---------------------------------------------------------------
 * Section reveal — fade + soft de-blur
 *
 * Client asked for something more intriguing than a plain rise: content
 * resolves INTO focus as its section enters. Blur is GPU-composited and
 * only ever animates on elements already being faded, so it costs one
 * layer and no layout. Kept slow and shallow — 6px, not a gimmick.
 * -------------------------------------------------------------- */
.js .reveal{
  opacity:0;
  filter:blur(6px);
  transform:translateY(22px);
  transition:opacity 1.15s var(--ease), filter 1.15s var(--ease), transform 1.15s var(--ease);
  will-change:opacity, filter, transform;
}
.js .reveal.in{opacity:1; filter:blur(0); transform:none;}
/* Drop the compositing hint once the element has arrived, so long pages do
   not hold dozens of promoted layers. */
.js .reveal.in{will-change:auto;}

.js .reveal.r1{transition-delay:.10s;}
.js .reveal.r2{transition-delay:.20s;}
.js .reveal.r3{transition-delay:.30s;}

/* The existing .rise keeps working; this simply adds the blur to it so the
   whole site gains the effect without re-tagging every widget. */
.js .rise{filter:blur(5px); transition:opacity 1.2s var(--ease), transform 1.2s var(--ease), filter 1.2s var(--ease);}
.js .rise.in{filter:blur(0);}

@media (prefers-reduced-motion:reduce){
  .js .reveal, .js .rise{filter:none !important; transform:none !important; opacity:1 !important;}
}

/* ---------------------------------------------------------------
 * Availability & rarity — the closing CTA
 *
 * Screenshots showed the three stats floating with no relationship to
 * each other, a long empty gap under the button, and the section
 * running much taller than it needed to. This tightens the vertical
 * rhythm, gives the stats hairline separators so they read as one
 * group, and pulls the note up under the button.
 * -------------------------------------------------------------- */
.finite{padding-top:clamp(90px,12vh,150px); padding-bottom:clamp(90px,12vh,150px);}
.finite .label{color:var(--faint);}
.finite h2{margin-bottom:26px; max-width:18ch; margin-left:auto; margin-right:auto;}
.finite .sub{max-width:48ch; color:var(--dim);}

/* stats read as one set: even columns, hairline dividers between */
.finite .stat{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:0; margin-top:clamp(48px,6vh,74px);
  border-top:1px solid var(--hair); border-bottom:1px solid var(--hair);
  padding:clamp(30px,4vh,44px) 0;
  max-width:820px; margin-left:auto; margin-right:auto;
}
.finite .stat > div{padding:0 18px; border-left:1px solid var(--hair);}
.finite .stat > div:first-child{border-left:none;}
.finite .stat .n{font-size:clamp(24px,2.6vw,36px); line-height:1.1; color:var(--fg);}
.finite .stat .k{margin-top:10px; font-size:10px; letter-spacing:0.18em;}
@media (max-width:720px){
  .finite .stat{grid-template-columns:1fr; gap:26px; padding:28px 0;}
  .finite .stat > div{border-left:none; padding:0;}
}

.finite .cta{margin-top:clamp(40px,5vh,58px);}
.finite .note{margin-top:20px; color:var(--faint); font-size:12px;}

/* ---------------------------------------------------------------
 * Privacy band — blend into the page
 *
 * The eyebrow is gone (client), so the headline leads. The band also
 * met the surrounding black with a hard horizontal edge; these masks
 * feather the top and bottom of the PHOTOGRAPH itself, so the image
 * dissolves into the page rather than sitting in a visible box.
 * -------------------------------------------------------------- */
.privacy{height:auto; min-height:0; padding:clamp(96px,14vh,170px) 0;}
.privacy .pimg{
  -webkit-mask-image:linear-gradient(180deg, transparent 0%, #000 16%, #000 82%, transparent 100%);
          mask-image:linear-gradient(180deg, transparent 0%, #000 16%, #000 82%, transparent 100%);
}

/* QA issue 03 / staging #11: two CONSECUTIVE full-bleed bands ran together.
   Each already fades to black at both ends, which works against the page — but
   when two meet, both fades land in the same place and the seam disappears, so
   the Story page read as one continuous photograph behind two headlines.
   Adjacent bands get a hairline and extra breathing room; a single band is
   untouched, so the cinematic full-bleed treatment is preserved everywhere it
   was working. */
/* Elementor wraps every widget in its own top-level <section>, so the bands
   are NEVER DOM siblings — `.privacy + .privacy` matches nothing here, which I
   confirmed against the live DOM. The adjacency has to be read one level up,
   between the Elementor sections that contain them. */
.elementor-top-section:has(.privacy) + .elementor-top-section:has(.privacy) .privacy{
  border-top:1px solid var(--hair);
  padding-top:clamp(150px,24vh,260px);
}
.privacy h2{font-size:clamp(34px,5vw,74px); line-height:1.04;}
.privacy p{margin-top:26px; color:var(--dim); font-size:16px;}
@media (max-width:900px){
  .privacy{padding:clamp(90px,14vh,140px) 0;}
  .privacy .p-in{max-width:100%;}
}

/* ---------------------------------------------------------------
 * Caseback section
 *
 * Photograph left, the reading of it right. The engraving is set in the
 * mono face because it is a transcription of a physical object, not copy.
 * -------------------------------------------------------------- */
.sn-back__grid{
  display:grid; grid-template-columns:0.95fr 1.05fr;
  gap:clamp(40px,6vw,100px); align-items:center;
  margin-top:clamp(40px,6vh,72px);
}
@media (max-width:900px){.sn-back__grid{grid-template-columns:1fr; gap:44px;}}

.sn-back__fig{
  margin:0; position:relative; background:#000;
  border:1px solid var(--hair); overflow:hidden; aspect-ratio:3/4;
}
.sn-back__fig img{width:100%; height:100%; object-fit:cover; display:block;}
.sn-back__fig::after{
  /* the same pool of light used under the configurator */
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 70% 60% at 50% 46%, transparent 58%, rgba(11,10,9,0.55) 100%);
}

.sn-back__txt h2{
  font-weight:300; font-size:clamp(30px,3.8vw,56px); line-height:1.08;
  letter-spacing:-0.025em; max-width:16ch; margin:0 0 clamp(22px,3vh,32px);
}
.sn-back__body{
  font-size:clamp(15px,1.35vw,17px); line-height:1.85; color:var(--dim);
  max-width:52ch; margin:0 0 clamp(30px,4vh,44px);
}
.sn-back__engraving{
  display:flex; flex-direction:column; gap:9px;
  padding:clamp(20px,2.6vw,28px);
  border:1px solid var(--hair); background:rgba(255,255,255,0.02);
  max-width:44ch;
}
.sn-back__engraving span{
  font-size:12px; letter-spacing:0.05em; color:var(--dim); line-height:1.5;
}
.sn-back__engraving span:last-child{color:var(--fg);}

/* ---------------------------------------------------------------
 * MOBILE NAVIGATION
 *
 * The header previously had NO responsive handling at all: five links
 * plus the language switcher sat on one row at every width, so on a
 * 390px phone the nav ran from 28px to 475px — well off-screen and
 * unreachable. This adds a proper panel below 900px.
 *
 * The toggle is hidden on desktop, so large screens are untouched.
 * -------------------------------------------------------------- */
.nav-toggle{
  display:none; position:relative; z-index:2;
  width:44px; height:44px;              /* 44px: minimum comfortable tap target */
  margin-right:-10px;
  background:none; border:none; padding:0; cursor:pointer;
  -webkit-appearance:none; appearance:none;
}
/* Three bars at 2px: a 1px hairline is almost invisible on a phone and
   disappears entirely at low display scaling. */
.nav-toggle__bars{display:block; width:24px; height:14px; position:relative; margin:0 auto;}
.nav-toggle__bars i{
  position:absolute; left:0; right:0; height:2px; background:var(--fg); border-radius:1px;
  transition:transform .4s var(--ease), opacity .25s var(--ease);
}
.nav-toggle__bars i:nth-child(1){top:0;}
.nav-toggle__bars i:nth-child(2){top:6px;}
.nav-toggle__bars i:nth-child(3){top:12px;}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(1){transform:translateY(6px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(2){opacity:0;}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(3){transform:translateY(-6px) rotate(-45deg);}

@media (max-width:900px){
  .nav-toggle{display:block;}

  header#nav{padding:18px var(--edge);}
  header#nav .logo{height:21px; width:auto;}

  /* The menu becomes a full-height panel. Fixed rather than absolute so it
     is unaffected by the header's own transform/backdrop-filter. */
  header nav{
    position:fixed; inset:0;
    /* QA issue 01 (16 Sep): page content showed THROUGH the open menu on a
       real device — "JOURNAL" and "CONTACT" were legible over the article
       beneath. Two causes, both fixed here:
         1. z-index:1 put the panel at the bottom of the header's own stacking
            context, so anything painted later could sit above it. It now sits
            just under the header bar (100) and above all page content.
         2. The background was rgba(...,0.97) plus a backdrop-filter. When the
            blur is unavailable or dropped under memory pressure — common on
            iOS Safari — the 3% translucency is all that remains and the page
            reads straight through it. The fill is now FULLY OPAQUE; the blur
            stays as an enhancement only, and nothing depends on it. */
    z-index:99;
    display:flex; flex-direction:column; justify-content:flex-start; align-items:flex-start;
    gap:0;
    /* Start below the header bar rather than floating mid-panel: with
       justify-content:center the first link sat 265px down the screen. */
    padding:calc(80px + clamp(28px,7vh,64px)) var(--edge) 0;
    background:#0B0A09;
    -webkit-backdrop-filter:blur(20px); backdrop-filter:blur(20px);
    opacity:0; visibility:hidden; pointer-events:none;
    transition:opacity .45s var(--ease), visibility .45s var(--ease);
  }
  header nav.is-open{opacity:1; visibility:visible; pointer-events:auto;}

  /* ★★ THE ACTUAL CAUSE of the menu overlapping page content.
     `backdrop-filter` on the header creates a CONTAINING BLOCK for fixed-
     position descendants. So `#nav-menu{position:fixed; inset:0}` was being
     trapped inside the header's own 80px box — measured: 390x80 instead of
     390x844 — and the links painted over the article beneath. It only
     appeared AFTER SCROLLING because the filter lives on `header.scrolled`,
     which is exactly what the QA report described.
     While the menu is open the header drops the filter, so the panel escapes
     and covers the viewport. The blur is decorative and is not missed for the
     moment the menu is up. */
  body.nav-open header.scrolled,
  header.scrolled:has(nav.is-open){
    -webkit-backdrop-filter:none;
            backdrop-filter:none;
    background:transparent;
    border-bottom-color:transparent;
  }

  header nav a{
    display:block; width:100%;
    font-size:20px; letter-spacing:0.1em; color:var(--fg);
    padding:16px 0;                       /* generous tap targets */
    border-bottom:1px solid var(--hair);
    opacity:0; transform:translateY(14px);
    transition:opacity .5s var(--ease), transform .5s var(--ease);
  }
  header nav.is-open a{opacity:1; transform:none;}
  /* Stagger the links in, matching the site's motion language. */
  header nav.is-open a:nth-child(1){transition-delay:.06s;}
  header nav.is-open a:nth-child(2){transition-delay:.12s;}
  header nav.is-open a:nth-child(3){transition-delay:.18s;}
  header nav.is-open a:nth-child(4){transition-delay:.24s;}
  header nav.is-open a:nth-child(5){transition-delay:.30s;}
  header nav a.here{color:var(--fg);}
  header nav a:last-of-type{border-bottom:none;}

  header .lang,
  header .sn-lang{
    margin-top:30px; font-size:12px; color:var(--dim);
    opacity:0; transition:opacity .5s var(--ease) .34s;
  }
  header nav.is-open .lang,
  header nav.is-open .sn-lang{opacity:1;}
  /* 14px on phones: a tap target, not a footnote. */
  header .sn-lang__item{font-size:14px; padding:6px 0;}

  /* Lock the page while the panel is open. */
  body.nav-open{overflow:hidden;}
}

/* ---------------------------------------------------------------
 * PHONE REFINEMENTS  (≤ 560px)
 *
 * Tablet is largely handled by the existing 900px rules; these are the
 * phone-specific corrections found by measuring real layout at 390px.
 * -------------------------------------------------------------- */
@media (max-width:560px){

  /* Tighter page gutter: --edge clamps to 28px, which eats a 390px screen. */
  :root{--edge:20px;}

  /* Type scale: the clamp() minimums were still set for tablet. */
  /* 5.6vw keeps the longest line inside a 390px screen; the previous
     26px minimum pushed "your wrist." off the right edge. */
  .hero h1{font-size:clamp(21px,5.6vw,30px); line-height:1.2;}
  .idea .lead,
  .duo .lead,
  .craft .lead{font-size:clamp(24px,6.6vw,32px); line-height:1.14;}
  .privacy h2{font-size:clamp(26px,7.2vw,36px);}
  .finite h2{font-size:clamp(28px,8vw,40px); line-height:1.06;}
  .sn-back__txt h2{font-size:clamp(24px,6.8vw,32px);}

  /* Full-height bands are oppressive on a small screen. */
  .hero{min-height:82vh;}
  .privacy{padding:clamp(70px,11vh,110px) 0;}
  section.block{padding:clamp(64px,9vh,98px) 0;}

  /* Section heads wrap rather than crushing the hairline to nothing. */
  .sechead{flex-wrap:wrap; gap:10px 14px;}
  .sechead .rule{min-width:40px;}

  /* Stats stack; the 3-up grid is unreadable at this width. */
  .finite .stat{grid-template-columns:1fr; gap:24px;}
  .finite .stat > div{border-left:none; padding:0;}

  /* Buttons: full width and a comfortable height. */
  .sn-cta,
  .finite .cta,
  .woocommerce #place_order,
  .woocommerce button.button{width:100%; text-align:center; padding:18px 24px;}
  .sn-form__foot{flex-direction:column; align-items:stretch;}
  .sn-form__foot .sn-cta{width:100%;}

  /* Configurator: options need real tap targets. */
  .sn-cfg__opt{padding:13px 15px; font-size:14px;}
  /* NOT 1/1 on a phone: the photograph is 3:4, so a square stage letterboxed
     it and the watch read as cropped and small — the reported fault. */
  .sn-cfg__stage{aspect-ratio:3/4;}

  /* Caseback stacks image over text. */
  .sn-back__grid{grid-template-columns:1fr; gap:32px;}
  .sn-back__fig{aspect-ratio:4/5;}
  .sn-back__engraving{max-width:100%;}
}

/* ---------------------------------------------------------------
 * TOUCH DEVICES
 *
 * Hover styles that only reveal on :hover are invisible on touch, and
 * "sticky hover" leaves them stuck after a tap. Give touch users the
 * resting state and use :active for feedback instead.
 * -------------------------------------------------------------- */
@media (hover:none){
  .sn-cta:active,
  .finite .cta:active{background:var(--fg); color:var(--black);}
  .sn-cfg__opt:active{border-color:rgba(255,255,255,0.6); color:var(--fg);}
  /* Never leave a hover-only affordance as the sole indicator. */
  .jcard .fig img,
  .cr-fig img{transform:none;}
}

/* Inputs must be ≥16px or iOS Safari zooms the page on focus — which then
   leaves the layout scrolled sideways. This applies at every width. */
@media (max-width:900px){
  .sn-field input[type="text"],
  .sn-field input[type="email"],
  .sn-field textarea,
  .sn-field select,
  .woocommerce form .form-row input.input-text,
  .woocommerce form .form-row textarea,
  .woocommerce form .form-row select,
  .sn-gate__form input[type="password"]{font-size:16px;}
}

/* ---------------------------------------------------------------
 * Overflow guards
 *
 * A single long word or an un-wrapped headline can push the whole page
 * sideways on a phone, which then makes every section look broken. These
 * are cheap insurance and cost nothing on desktop.
 * -------------------------------------------------------------- */
/* ★ overflow-x:hidden on <body> SILENTLY BREAKS position:sticky.
   Any overflow other than `visible` on an ancestor makes a sticky descendant
   scroll normally — the product page's sticky photograph never held because of
   this rule. Clamping on <html> alone stops horizontal scroll just as well and
   leaves <body> a valid containing block for sticky. Do not move it back. */
html{max-width:100%; overflow-x:hidden;}
body{max-width:100%;}

h1, h2, h3, p, span, a, li, dt, dd{overflow-wrap:break-word;}

/* Long unbroken strings — serials, emails, URLs — must never widen the page. */
.sn-back__engraving span,
.sn-review__sku,
.mono{overflow-wrap:anywhere;}

@media (max-width:560px){
  /* The hero column has its own padding; make sure the text box itself can
     never exceed the viewport. */
  .hero .h-in{width:100%; max-width:100%; padding-left:var(--edge); padding-right:var(--edge);}
  .hero h1{max-width:100%;}
}

/* ---------------------------------------------------------------
 * Phone: remaining type + rhythm corrections (≤ 560px)
 * -------------------------------------------------------------- */
@media (max-width:560px){

  /* Section heads: the number/name and the right-hand label were colliding
     on a narrow screen. Let the label drop to its own line. */
  .sechead .label{width:100%; text-align:left;}
  .sechead .num-idx{font-size:11px; letter-spacing:0.18em;}

  /* Two Systems: the pair becomes a stack with real separation. */
  .duo .cols{gap:38px;}
  .duo .cell{padding-top:26px; border-top:1px solid var(--hair);}
  /* The first cell drops its top padding so it does not double the space under
     the section headline. But when a PHOTOGRAPH sits above the cells, that
     left the first block flush against the image while the second had 26px —
     the asymmetry the review reported (staging #7 / doc A issue 07). With a
     figure present, the first cell gets the same breathing room as its
     sibling, so comparable blocks read with one rhythm. */
  .duo .cell:first-child{border-top:none; padding-top:0;}
  .duo__fig ~ .cols .cell:first-child{padding-top:26px;}

  /* Statement body copy sized for a phone measure. */
  .idea .body{font-size:15px; line-height:1.8;}
  .idea .lead{max-width:100%;}

  /* Privacy copy should not run to the very edge. */
  .privacy .p-in{max-width:100%;}
  .privacy p{font-size:15px;}

  /* Configurator: label + options stack cleanly, stage not too tall. */
  .sn-cfg{padding:16px;}
  .sn-cfg__legend{margin-bottom:10px;}
  .sn-cfg__foot{align-items:stretch;}
  .sn-cfg__meta{text-align:center;}

  /* Caseback engraving comfortable to read. */
  .sn-back__engraving span{font-size:11.5px;}

  /* Closing CTA. */
  .finite .sub{font-size:15px;}
  .finite .stat .n{font-size:26px;}
  .finite .note{font-size:11.5px;}

  /* Footer: .fgrid already stacks at this width; these tune the rest. */
  .fbot{flex-direction:column; align-items:flex-start; gap:14px;}
  .sn-newsletter input{font-size:16px;}   /* no iOS zoom-on-focus */
}

/* ---------------------------------------------------------------
 * Hero slides
 *
 * The hero cycles as SLIDES: each photograph is paired with its own
 * headline, so the whole section changes rather than an image sliding
 * behind fixed type.
 *
 * Pure CSS animation — no JavaScript, so a slow CDN can never leave the
 * hero blank. Slide one is the resting state and is what a
 * reduced-motion user sees.
 *
 * Timing: each slide holds, then cross-fades. 9s per slide.
 * -------------------------------------------------------------- */
.hero .hslide{
  opacity:0;
  /* a very slight scale drift so a change reads as a settle, not a cut */
  transform:scale(1.04);
  transition:transform 1.6s var(--ease);
}
.hero .hslide--1{opacity:1;}          /* always the fallback */

/*
 * Light veil.
 *
 * A soft wash of light crosses the frame exactly as the slides swap, so the
 * change is covered by a movement of light rather than a visible dissolve.
 * This is the Charte's "jeux de lumière" — light revealing the black — used
 * as the transition itself. Pointer-events off; it is purely decorative.
 */
.hero::after{
  content:"";
  /* Above the photograph and its scrim, BELOW the type (z-index 3), so the
     light passes across the image without washing over the headline. */
  position:absolute; inset:0; z-index:2;
  pointer-events:none;
  opacity:0;
  background:radial-gradient(120% 70% at 50% 50%, rgba(255,255,255,0.16) 0%, rgba(255,255,255,0.05) 38%, transparent 70%);
  mix-blend-mode:screen;
}
.hero--slides-2::after{animation:sn-veil2 18s var(--ease) infinite;}
.hero--slides-3::after{animation:sn-veil3 27s var(--ease) infinite;}

/* Peaks at each hand-over, invisible the rest of the time. */
@keyframes sn-veil2{
  0%,40%   {opacity:0;}
  47%      {opacity:1;}
  54%,90%  {opacity:0;}
  97%      {opacity:1;}
  100%     {opacity:0;}
}
@keyframes sn-veil3{
  0%,26%   {opacity:0;}
  32%      {opacity:1;}
  38%,59%  {opacity:0;}
  65%      {opacity:1;}
  71%,92%  {opacity:0;}
  97%      {opacity:1;}
  100%     {opacity:0;}
}
.hero .htext{position:absolute; opacity:0; pointer-events:none;}
.hero .htext--1{position:relative; opacity:1; pointer-events:auto;}

/* --- two slides: 18s cycle --- */
.hero--slides-2 .hslide--1{animation:sn-sl2a 18s var(--ease) infinite;}
.hero--slides-2 .hslide--2{animation:sn-sl2b 18s var(--ease) infinite;}
.hero--slides-2 .htext--1{animation:sn-tx2a 18s var(--ease) infinite;}
.hero--slides-2 .htext--2{animation:sn-tx2b 18s var(--ease) infinite;}

@keyframes sn-sl2a{
  0%      {opacity:1; transform:scale(1);}
  44%     {opacity:1; transform:scale(1.035);}
  50%,94% {opacity:0; transform:scale(1.04);}
  100%    {opacity:1; transform:scale(1);}
}
@keyframes sn-sl2b{
  0%,44%  {opacity:0; transform:scale(1.04);}
  50%     {opacity:1; transform:scale(1);}
  94%     {opacity:1; transform:scale(1.035);}
  100%    {opacity:0; transform:scale(1.04);}
}
/* Text leads the image out and follows it in, so the words are never
   caught mid-dissolve against the wrong photograph. */
@keyframes sn-tx2a{ 0%,40%{opacity:1} 46%,96%{opacity:0} 100%{opacity:1} }
@keyframes sn-tx2b{ 0%,46%{opacity:0} 52%,90%{opacity:1} 96%,100%{opacity:0} }

/* --- three slides: 27s cycle --- */
.hero--slides-3 .hslide--1{animation:sn-sl3a 27s var(--ease) infinite;}
.hero--slides-3 .hslide--2{animation:sn-sl3b 27s var(--ease) infinite;}
.hero--slides-3 .hslide--3{animation:sn-sl3c 27s var(--ease) infinite;}
.hero--slides-3 .htext--1{animation:sn-tx3a 27s var(--ease) infinite;}
.hero--slides-3 .htext--2{animation:sn-tx3b 27s var(--ease) infinite;}
.hero--slides-3 .htext--3{animation:sn-tx3c 27s var(--ease) infinite;}

@keyframes sn-sl3a{
  0%      {opacity:1; transform:scale(1);}
  29%     {opacity:1; transform:scale(1.03);}
  35%,96% {opacity:0; transform:scale(1.04);}
  100%    {opacity:1; transform:scale(1);}
}
@keyframes sn-sl3b{
  0%,29%  {opacity:0; transform:scale(1.04);}
  35%     {opacity:1; transform:scale(1);}
  62%     {opacity:1; transform:scale(1.03);}
  68%,100%{opacity:0; transform:scale(1.04);}
}
@keyframes sn-sl3c{
  0%,62%  {opacity:0; transform:scale(1.04);}
  68%     {opacity:1; transform:scale(1);}
  95%     {opacity:1; transform:scale(1.03);}
  100%    {opacity:0; transform:scale(1.04);}
}
@keyframes sn-tx3a{ 0%,26%{opacity:1} 32%,97%{opacity:0} 100%{opacity:1} }
@keyframes sn-tx3b{ 0%,32%{opacity:0} 38%,59%{opacity:1} 65%,100%{opacity:0} }
@keyframes sn-tx3c{ 0%,65%{opacity:0} 71%,92%{opacity:1} 97%,100%{opacity:0} }

/* --- progress marks --- */
.hdots{
  position:absolute; left:var(--edge); bottom:38px; z-index:3;
  display:flex; gap:10px;
}
.hdot{
  width:22px; height:1px; background:rgba(255,255,255,0.22);
  position:relative; overflow:hidden;
}
.hdot::after{
  content:""; position:absolute; inset:0; background:var(--fg);
  transform:scaleX(0); transform-origin:left;
}
.hero--slides-2 .hdot--1::after{animation:sn-dot2a 18s linear infinite;}
.hero--slides-2 .hdot--2::after{animation:sn-dot2b 18s linear infinite;}
@keyframes sn-dot2a{ 0%{transform:scaleX(0)} 44%{transform:scaleX(1)} 50%,100%{transform:scaleX(0)} }
@keyframes sn-dot2b{ 0%,50%{transform:scaleX(0)} 94%{transform:scaleX(1)} 100%{transform:scaleX(0)} }

.hero--slides-3 .hdot--1::after{animation:sn-dot3a 27s linear infinite;}
.hero--slides-3 .hdot--2::after{animation:sn-dot3b 27s linear infinite;}
.hero--slides-3 .hdot--3::after{animation:sn-dot3c 27s linear infinite;}
@keyframes sn-dot3a{ 0%{transform:scaleX(0)} 29%{transform:scaleX(1)} 35%,100%{transform:scaleX(0)} }
@keyframes sn-dot3b{ 0%,35%{transform:scaleX(0)} 62%{transform:scaleX(1)} 68%,100%{transform:scaleX(0)} }
@keyframes sn-dot3c{ 0%,68%{transform:scaleX(0)} 95%{transform:scaleX(1)} 100%{transform:scaleX(0)} }

@media (max-width:760px){ .hdots{left:var(--edge); bottom:26px;} }

/* Reduced motion: no cycling at all — slide one, held. */
@media (prefers-reduced-motion:reduce){
  .hero .hslide,
  .hero .htext,
  .hero::after,
  .hdot::after{animation:none !important;}
  .hero::after{opacity:0 !important;}
  .hero .hslide{transform:none !important;}
  .hero .hslide--1,
  .hero .htext--1{opacity:1 !important;}
  .hero .hslide:not(.hslide--1),
  .hero .htext:not(.htext--1){opacity:0 !important;}
  .hdots{display:none;}
}

/* ---------------------------------------------------------------
 * Hero — brand presence and the offer, above the fold
 *
 * The hero was a photograph with one sentence on it: no mark, no
 * reference, no price, nothing to act on. These three additions fix
 * that without adding noise — a hairline strip at the top, and a
 * button + meta line under the headline.
 * -------------------------------------------------------------- */
.hero .h-top{
  position:absolute; top:0; left:0; right:0; z-index:3;
  display:flex; align-items:center; gap:20px;
  padding:calc(var(--edge) * 0.42) var(--edge) 0;
}
.hero .h-top .label{color:rgba(255,255,255,0.62); white-space:nowrap;}
.hero .h-top__rule{flex:1; height:1px; background:rgba(255,255,255,0.14);}
@media (max-width:760px){
  .hero .h-top{padding-top:22px; gap:12px;}
  .hero .h-top .label{font-size:9px; letter-spacing:0.24em;}
}

.hero .h-meta{
  display:flex; flex-direction:column; align-items:flex-start; gap:18px;
  margin-top:clamp(30px,4vh,46px);
}
/* Set on its own line and allowed to breathe: as a single run it wrapped
   mid-phrase ("...December / 2026"), which reads like a mistake. */
.hero .h-meta__line{
  font-size:11px; line-height:1.9; letter-spacing:0.04em;
  color:rgba(255,255,255,0.58); text-shadow:0 2px 24px rgba(0,0,0,0.9);
  max-width:38ch;
}
@media (max-width:760px){
  .hero .h-meta{gap:14px; margin-top:24px;}
  .hero .h-meta .sn-cta{padding:16px 34px; font-size:11px;}
}
/* The meta block shares the hero's staged entrance. */
.js .hero .h-meta{opacity:0; transform:translateY(16px); transition:opacity 1.2s var(--ease), transform 1.2s var(--ease);}
.js .hero .h-meta.in{opacity:1; transform:none;}

/* ---------------------------------------------------------------
 * Configurator — give it the weight of a product display
 *
 * It was floating on the page background with no edge, which made the
 * most important section on the homepage read as the least finished.
 * -------------------------------------------------------------- */
.sn-configure{
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,0.035) 0%, transparent 62%),
    var(--black);
}
.sn-cfg{
  border:1px solid var(--hair);
  background:linear-gradient(180deg, rgba(255,255,255,0.02), transparent 55%);
  padding:clamp(22px,3vw,46px);
  gap:clamp(26px,4vw,64px);
}
.sn-cfg__stage{
  border:none; background:transparent;
  aspect-ratio:1/1;
}
.sn-cfg__stage::after{
  /* a soft pool of light under the watch, per the Charte's clair-obscur */
  content:""; position:absolute; left:50%; bottom:6%; transform:translateX(-50%);
  width:62%; height:16%; border-radius:50%;
  background:radial-gradient(ellipse at center, rgba(255,255,255,0.09), transparent 70%);
  pointer-events:none; z-index:0;
}
.sn-cfg__img{position:relative; z-index:1;}
.sn-cfg__panel{gap:clamp(20px,2.8vh,32px);}

/* On the homepage the craft band is a breath between choosing and
   committing, not a destination in itself — so it runs shorter than the
   full-height version used on the SN 2140 page. */
.home .moment{height:76vh; min-height:520px;}
@media (max-width:760px){.home .moment{height:56vh; min-height:380px;}}

/* ---------------------------------------------------------------
 * Hero, retuned for the 2026 wrist photography.
 *
 * The portrait wrist shot is a dark subject on a dark ground, framed
 * loosely. Straight `cover` at 100vh left the watch small in a large
 * black field, and the original scrim (built for a left-weighted product
 * render) darkened it further. Three corrections: scale into the frame so
 * the watch reads, lift the midtones, and darken only the right side
 * where the type actually sits.
 * -------------------------------------------------------------- */
.home .hero .himg{
  background-position:44% 30%;
  background-size:132% auto;
  filter:brightness(1.28) contrast(1.04);
}
.home .hero .hgrade{
  background:
    /* Stronger, and it begins further left: the type column starts around 54%,
       and each slide frames the watch differently, so the ramp has to be dark
       enough by then for ANY of the three photographs. */
    linear-gradient(90deg,
      rgba(11,10,9,0.34) 0%,
      rgba(11,10,9,0.00) 20%,
      rgba(11,10,9,0.10) 38%,
      rgba(11,10,9,0.58) 54%,
      rgba(11,10,9,0.88) 72%,
      rgba(11,10,9,0.96) 100%),
    linear-gradient(180deg,
      rgba(11,10,9,0.70) 0%,
      transparent 22%,
      transparent 62%,
      rgba(11,10,9,0.86) 90%,
      var(--black) 100%);
}
@media (max-width:900px){
  .home .hero .himg{background-position:50% 26%; background-size:150% auto;}
  .home .hero .hgrade{
    background:linear-gradient(180deg, rgba(11,10,9,0.60) 0%, transparent 24%, rgba(11,10,9,0.90) 70%, var(--black) 100%);
  }
}

/* The type column sits slightly above centre: with the CTA and meta line
   added it was bottom-weighted, leaving a dead band under the fold. */
.home .hero{align-items:center;}
.home .hero .h-in{transform:translateY(-4vh);}
@media (max-width:900px){.home .hero .h-in{transform:none;}}

/* Mobile stacking, re-declared LAST.
   The polish block above re-sets `gap` on .sn-cfg, which came after the
   original max-width:900px rule and silently defeated its gap. Ordering
   matters here — keep this the final word on the configurator grid. */
@media (max-width:900px){
  .sn-cfg{grid-template-columns:1fr; gap:36px; padding:clamp(18px,4vw,28px);}
  /* 3/4 matches the source art (1200x1600). At 4/5 the stage was TALLER than
     the photograph, so object-fit:contain letterboxed it and the watch read as
     cropped and small on a phone. */
  .sn-cfg__stage{aspect-ratio:3/4;}
}

/* ---------------------------------------------------------------
 * Statement section (03 · The House)
 *
 * `.idea .body` previously had NO rules at all — only a grid override
 * inside a max-width:900px media query, which never applied on desktop.
 * So the paragraph ran the full 1360px measure and sat flush against the
 * headline: no separation, unreadable line length, exactly the "spacing
 * feels off" note. It needs a measure, a rhythm and space above.
 * -------------------------------------------------------------- */
.idea .lead{margin-bottom:clamp(28px,4vh,52px);}
.idea .body{
  max-width:62ch;
  font-size:clamp(15px,1.35vw,17px);
  line-height:1.85;
  color:var(--dim);
  margin:0;
}
/* The headline sets its own measure; on wide screens 16ch is very narrow for
   a three-line sentence, so let it breathe a little further. */
.idea .lead{max-width:22ch;}
@media (max-width:900px){
  .idea .lead{max-width:18ch;}
  .idea .body{max-width:100%; font-size:15px;}
}

/* ---------------------------------------------------------------
 * Closing CTA — the last thing before the footer.
 *
 * It now ends the page rather than sitting mid-scroll, so it carries a
 * little more weight: a faint pool of light behind it and a hairline
 * above, without becoming a loud "buy now" panel.
 * -------------------------------------------------------------- */
.finite{
  position:relative;
  border-top:1px solid var(--hair);
  background:radial-gradient(120% 100% at 50% 100%, rgba(255,255,255,0.045) 0%, transparent 60%), var(--black);
}
.finite .stat{border-top:1px solid var(--hair); padding-top:clamp(38px,5vh,58px);}
.finite .cta{margin-top:clamp(46px,6vh,66px);}

/* ---------------------------------------------------------------
 * Section reveal — fade + soft de-blur
 *
 * Client asked for something more intriguing than a plain rise: content
 * resolves INTO focus as its section enters. Blur is GPU-composited and
 * only ever animates on elements already being faded, so it costs one
 * layer and no layout. Kept slow and shallow — 6px, not a gimmick.
 * -------------------------------------------------------------- */
.js .reveal{
  opacity:0;
  filter:blur(6px);
  transform:translateY(22px);
  transition:opacity 1.15s var(--ease), filter 1.15s var(--ease), transform 1.15s var(--ease);
  will-change:opacity, filter, transform;
}
.js .reveal.in{opacity:1; filter:blur(0); transform:none;}
/* Drop the compositing hint once the element has arrived, so long pages do
   not hold dozens of promoted layers. */
.js .reveal.in{will-change:auto;}

.js .reveal.r1{transition-delay:.10s;}
.js .reveal.r2{transition-delay:.20s;}
.js .reveal.r3{transition-delay:.30s;}

/* The existing .rise keeps working; this simply adds the blur to it so the
   whole site gains the effect without re-tagging every widget. */
.js .rise{filter:blur(5px); transition:opacity 1.2s var(--ease), transform 1.2s var(--ease), filter 1.2s var(--ease);}
.js .rise.in{filter:blur(0);}

@media (prefers-reduced-motion:reduce){
  .js .reveal, .js .rise{filter:none !important; transform:none !important; opacity:1 !important;}
}

/* ---------------------------------------------------------------
 * Availability & rarity — the closing CTA
 *
 * Screenshots showed the three stats floating with no relationship to
 * each other, a long empty gap under the button, and the section
 * running much taller than it needed to. This tightens the vertical
 * rhythm, gives the stats hairline separators so they read as one
 * group, and pulls the note up under the button.
 * -------------------------------------------------------------- */
.finite{padding-top:clamp(90px,12vh,150px); padding-bottom:clamp(90px,12vh,150px);}
.finite .label{color:var(--faint);}
.finite h2{margin-bottom:26px; max-width:18ch; margin-left:auto; margin-right:auto;}
.finite .sub{max-width:48ch; color:var(--dim);}

/* stats read as one set: even columns, hairline dividers between */
.finite .stat{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:0; margin-top:clamp(48px,6vh,74px);
  border-top:1px solid var(--hair); border-bottom:1px solid var(--hair);
  padding:clamp(30px,4vh,44px) 0;
  max-width:820px; margin-left:auto; margin-right:auto;
}
.finite .stat > div{padding:0 18px; border-left:1px solid var(--hair);}
.finite .stat > div:first-child{border-left:none;}
.finite .stat .n{font-size:clamp(24px,2.6vw,36px); line-height:1.1; color:var(--fg);}
.finite .stat .k{margin-top:10px; font-size:10px; letter-spacing:0.18em;}
@media (max-width:720px){
  .finite .stat{grid-template-columns:1fr; gap:26px; padding:28px 0;}
  .finite .stat > div{border-left:none; padding:0;}
}

.finite .cta{margin-top:clamp(40px,5vh,58px);}
.finite .note{margin-top:20px; color:var(--faint); font-size:12px;}

/* ---------------------------------------------------------------
 * Privacy band — blend into the page
 *
 * The eyebrow is gone (client), so the headline leads. The band also
 * met the surrounding black with a hard horizontal edge; these masks
 * feather the top and bottom of the PHOTOGRAPH itself, so the image
 * dissolves into the page rather than sitting in a visible box.
 * -------------------------------------------------------------- */
.privacy{height:auto; min-height:0; padding:clamp(96px,14vh,170px) 0;}
.privacy .pimg{
  -webkit-mask-image:linear-gradient(180deg, transparent 0%, #000 16%, #000 82%, transparent 100%);
          mask-image:linear-gradient(180deg, transparent 0%, #000 16%, #000 82%, transparent 100%);
}

/* QA issue 03 / staging #11: two CONSECUTIVE full-bleed bands ran together.
   Each already fades to black at both ends, which works against the page — but
   when two meet, both fades land in the same place and the seam disappears, so
   the Story page read as one continuous photograph behind two headlines.
   Adjacent bands get a hairline and extra breathing room; a single band is
   untouched, so the cinematic full-bleed treatment is preserved everywhere it
   was working. */
/* Elementor wraps every widget in its own top-level <section>, so the bands
   are NEVER DOM siblings — `.privacy + .privacy` matches nothing here, which I
   confirmed against the live DOM. The adjacency has to be read one level up,
   between the Elementor sections that contain them. */
.elementor-top-section:has(.privacy) + .elementor-top-section:has(.privacy) .privacy{
  border-top:1px solid var(--hair);
  padding-top:clamp(150px,24vh,260px);
}
.privacy h2{font-size:clamp(34px,5vw,74px); line-height:1.04;}
.privacy p{margin-top:26px; color:var(--dim); font-size:16px;}
@media (max-width:900px){
  .privacy{padding:clamp(90px,14vh,140px) 0;}
  .privacy .p-in{max-width:100%;}
}

/* ---------------------------------------------------------------
 * Caseback section
 *
 * Photograph left, the reading of it right. The engraving is set in the
 * mono face because it is a transcription of a physical object, not copy.
 * -------------------------------------------------------------- */
.sn-back__grid{
  display:grid; grid-template-columns:0.95fr 1.05fr;
  gap:clamp(40px,6vw,100px); align-items:center;
  margin-top:clamp(40px,6vh,72px);
}
@media (max-width:900px){.sn-back__grid{grid-template-columns:1fr; gap:44px;}}

.sn-back__fig{
  margin:0; position:relative; background:#000;
  border:1px solid var(--hair); overflow:hidden; aspect-ratio:3/4;
}
.sn-back__fig img{width:100%; height:100%; object-fit:cover; display:block;}
.sn-back__fig::after{
  /* the same pool of light used under the configurator */
  content:""; position:absolute; inset:0; pointer-events:none;
  background:radial-gradient(ellipse 70% 60% at 50% 46%, transparent 58%, rgba(11,10,9,0.55) 100%);
}

.sn-back__txt h2{
  font-weight:300; font-size:clamp(30px,3.8vw,56px); line-height:1.08;
  letter-spacing:-0.025em; max-width:16ch; margin:0 0 clamp(22px,3vh,32px);
}
.sn-back__body{
  font-size:clamp(15px,1.35vw,17px); line-height:1.85; color:var(--dim);
  max-width:52ch; margin:0 0 clamp(30px,4vh,44px);
}
.sn-back__engraving{
  display:flex; flex-direction:column; gap:9px;
  padding:clamp(20px,2.6vw,28px);
  border:1px solid var(--hair); background:rgba(255,255,255,0.02);
  max-width:44ch;
}
.sn-back__engraving span{
  font-size:12px; letter-spacing:0.05em; color:var(--dim); line-height:1.5;
}
.sn-back__engraving span:last-child{color:var(--fg);}

/* ---------------------------------------------------------------
 * MOBILE NAVIGATION
 *
 * The header previously had NO responsive handling at all: five links
 * plus the language switcher sat on one row at every width, so on a
 * 390px phone the nav ran from 28px to 475px — well off-screen and
 * unreachable. This adds a proper panel below 900px.
 *
 * The toggle is hidden on desktop, so large screens are untouched.
 * -------------------------------------------------------------- */
.nav-toggle{
  display:none; position:relative; z-index:2;
  width:44px; height:44px;              /* 44px: minimum comfortable tap target */
  margin-right:-10px;
  background:none; border:none; padding:0; cursor:pointer;
  -webkit-appearance:none; appearance:none;
}
/* Three bars at 2px: a 1px hairline is almost invisible on a phone and
   disappears entirely at low display scaling. */
.nav-toggle__bars{display:block; width:24px; height:14px; position:relative; margin:0 auto;}
.nav-toggle__bars i{
  position:absolute; left:0; right:0; height:2px; background:var(--fg); border-radius:1px;
  transition:transform .4s var(--ease), opacity .25s var(--ease);
}
.nav-toggle__bars i:nth-child(1){top:0;}
.nav-toggle__bars i:nth-child(2){top:6px;}
.nav-toggle__bars i:nth-child(3){top:12px;}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(1){transform:translateY(6px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(2){opacity:0;}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars i:nth-child(3){transform:translateY(-6px) rotate(-45deg);}

@media (max-width:900px){
  .nav-toggle{display:block;}

  header#nav{padding:18px var(--edge);}
  header#nav .logo{height:21px; width:auto;}

  /* The menu becomes a full-height panel. Fixed rather than absolute so it
     is unaffected by the header's own transform/backdrop-filter. */
  header nav{
    position:fixed; inset:0;
    /* QA issue 01 (16 Sep): page content showed THROUGH the open menu on a
       real device — "JOURNAL" and "CONTACT" were legible over the article
       beneath. Two causes, both fixed here:
         1. z-index:1 put the panel at the bottom of the header's own stacking
            context, so anything painted later could sit above it. It now sits
            just under the header bar (100) and above all page content.
         2. The background was rgba(...,0.97) plus a backdrop-filter. When the
            blur is unavailable or dropped under memory pressure — common on
            iOS Safari — the 3% translucency is all that remains and the page
            reads straight through it. The fill is now FULLY OPAQUE; the blur
            stays as an enhancement only, and nothing depends on it. */
    z-index:99;
    display:flex; flex-direction:column; justify-content:flex-start; align-items:flex-start;
    gap:0;
    /* Start below the header bar rather than floating mid-panel: with
       justify-content:center the first link sat 265px down the screen. */
    padding:calc(80px + clamp(28px,7vh,64px)) var(--edge) 0;
    background:#0B0A09;
    -webkit-backdrop-filter:blur(20px); backdrop-filter:blur(20px);
    opacity:0; visibility:hidden; pointer-events:none;
    transition:opacity .45s var(--ease), visibility .45s var(--ease);
  }
  header nav.is-open{opacity:1; visibility:visible; pointer-events:auto;}

  /* ★★ THE ACTUAL CAUSE of the menu overlapping page content.
     `backdrop-filter` on the header creates a CONTAINING BLOCK for fixed-
     position descendants. So `#nav-menu{position:fixed; inset:0}` was being
     trapped inside the header's own 80px box — measured: 390x80 instead of
     390x844 — and the links painted over the article beneath. It only
     appeared AFTER SCROLLING because the filter lives on `header.scrolled`,
     which is exactly what the QA report described.
     While the menu is open the header drops the filter, so the panel escapes
     and covers the viewport. The blur is decorative and is not missed for the
     moment the menu is up. */
  body.nav-open header.scrolled,
  header.scrolled:has(nav.is-open){
    -webkit-backdrop-filter:none;
            backdrop-filter:none;
    background:transparent;
    border-bottom-color:transparent;
  }

  header nav a{
    display:block; width:100%;
    font-size:20px; letter-spacing:0.1em; color:var(--fg);
    padding:16px 0;                       /* generous tap targets */
    border-bottom:1px solid var(--hair);
    opacity:0; transform:translateY(14px);
    transition:opacity .5s var(--ease), transform .5s var(--ease);
  }
  header nav.is-open a{opacity:1; transform:none;}
  /* Stagger the links in, matching the site's motion language. */
  header nav.is-open a:nth-child(1){transition-delay:.06s;}
  header nav.is-open a:nth-child(2){transition-delay:.12s;}
  header nav.is-open a:nth-child(3){transition-delay:.18s;}
  header nav.is-open a:nth-child(4){transition-delay:.24s;}
  header nav.is-open a:nth-child(5){transition-delay:.30s;}
  header nav a.here{color:var(--fg);}
  header nav a:last-of-type{border-bottom:none;}

  header .lang,
  header .sn-lang{
    margin-top:30px; font-size:12px; color:var(--dim);
    opacity:0; transition:opacity .5s var(--ease) .34s;
  }
  header nav.is-open .lang,
  header nav.is-open .sn-lang{opacity:1;}
  /* 14px on phones: a tap target, not a footnote. */
  header .sn-lang__item{font-size:14px; padding:6px 0;}

  /* Lock the page while the panel is open. */
  body.nav-open{overflow:hidden;}
}

/* ---------------------------------------------------------------
 * PHONE REFINEMENTS  (≤ 560px)
 *
 * Tablet is largely handled by the existing 900px rules; these are the
 * phone-specific corrections found by measuring real layout at 390px.
 * -------------------------------------------------------------- */
@media (max-width:560px){

  /* Tighter page gutter: --edge clamps to 28px, which eats a 390px screen. */
  :root{--edge:20px;}

  /* Type scale: the clamp() minimums were still set for tablet. */
  /* 5.6vw keeps the longest line inside a 390px screen; the previous
     26px minimum pushed "your wrist." off the right edge. */
  .hero h1{font-size:clamp(21px,5.6vw,30px); line-height:1.2;}
  .idea .lead,
  .duo .lead,
  .craft .lead{font-size:clamp(24px,6.6vw,32px); line-height:1.14;}
  .privacy h2{font-size:clamp(26px,7.2vw,36px);}
  .finite h2{font-size:clamp(28px,8vw,40px); line-height:1.06;}
  .sn-back__txt h2{font-size:clamp(24px,6.8vw,32px);}

  /* Full-height bands are oppressive on a small screen. */
  .hero{min-height:82vh;}
  .privacy{padding:clamp(70px,11vh,110px) 0;}
  section.block{padding:clamp(64px,9vh,98px) 0;}

  /* Section heads wrap rather than crushing the hairline to nothing. */
  .sechead{flex-wrap:wrap; gap:10px 14px;}
  .sechead .rule{min-width:40px;}

  /* Stats stack; the 3-up grid is unreadable at this width. */
  .finite .stat{grid-template-columns:1fr; gap:24px;}
  .finite .stat > div{border-left:none; padding:0;}

  /* Buttons: full width and a comfortable height. */
  .sn-cta,
  .finite .cta,
  .woocommerce #place_order,
  .woocommerce button.button{width:100%; text-align:center; padding:18px 24px;}
  .sn-form__foot{flex-direction:column; align-items:stretch;}
  .sn-form__foot .sn-cta{width:100%;}

  /* Configurator: options need real tap targets. */
  .sn-cfg__opt{padding:13px 15px; font-size:14px;}
  /* NOT 1/1 on a phone: the photograph is 3:4, so a square stage letterboxed
     it and the watch read as cropped and small — the reported fault. */
  .sn-cfg__stage{aspect-ratio:3/4;}

  /* Caseback stacks image over text. */
  .sn-back__grid{grid-template-columns:1fr; gap:32px;}
  .sn-back__fig{aspect-ratio:4/5;}
  .sn-back__engraving{max-width:100%;}
}

/* ---------------------------------------------------------------
 * TOUCH DEVICES
 *
 * Hover styles that only reveal on :hover are invisible on touch, and
 * "sticky hover" leaves them stuck after a tap. Give touch users the
 * resting state and use :active for feedback instead.
 * -------------------------------------------------------------- */
@media (hover:none){
  .sn-cta:active,
  .finite .cta:active{background:var(--fg); color:var(--black);}
  .sn-cfg__opt:active{border-color:rgba(255,255,255,0.6); color:var(--fg);}
  /* Never leave a hover-only affordance as the sole indicator. */
  .jcard .fig img,
  .cr-fig img{transform:none;}
}

/* Inputs must be ≥16px or iOS Safari zooms the page on focus — which then
   leaves the layout scrolled sideways. This applies at every width. */
@media (max-width:900px){
  .sn-field input[type="text"],
  .sn-field input[type="email"],
  .sn-field textarea,
  .sn-field select,
  .woocommerce form .form-row input.input-text,
  .woocommerce form .form-row textarea,
  .woocommerce form .form-row select,
  .sn-gate__form input[type="password"]{font-size:16px;}
}

/* ---------------------------------------------------------------
 * Overflow guards
 *
 * A single long word or an un-wrapped headline can push the whole page
 * sideways on a phone, which then makes every section look broken. These
 * are cheap insurance and cost nothing on desktop.
 * -------------------------------------------------------------- */
/* ★ overflow-x:hidden on <body> SILENTLY BREAKS position:sticky.
   Any overflow other than `visible` on an ancestor makes a sticky descendant
   scroll normally — the product page's sticky photograph never held because of
   this rule. Clamping on <html> alone stops horizontal scroll just as well and
   leaves <body> a valid containing block for sticky. Do not move it back. */
html{max-width:100%; overflow-x:hidden;}
body{max-width:100%;}

h1, h2, h3, p, span, a, li, dt, dd{overflow-wrap:break-word;}

/* Long unbroken strings — serials, emails, URLs — must never widen the page. */
.sn-back__engraving span,
.sn-review__sku,
.mono{overflow-wrap:anywhere;}

@media (max-width:560px){
  /* The hero column has its own padding; make sure the text box itself can
     never exceed the viewport. */
  .hero .h-in{width:100%; max-width:100%; padding-left:var(--edge); padding-right:var(--edge);}
  .hero h1{max-width:100%;}
}

/* ---------------------------------------------------------------
 * Phone: remaining type + rhythm corrections (≤ 560px)
 * -------------------------------------------------------------- */
@media (max-width:560px){

  /* Section heads: the number/name and the right-hand label were colliding
     on a narrow screen. Let the label drop to its own line. */
  .sechead .label{width:100%; text-align:left;}
  .sechead .num-idx{font-size:11px; letter-spacing:0.18em;}

  /* Two Systems: the pair becomes a stack with real separation. */
  .duo .cols{gap:38px;}
  .duo .cell{padding-top:26px; border-top:1px solid var(--hair);}
  /* The first cell drops its top padding so it does not double the space under
     the section headline. But when a PHOTOGRAPH sits above the cells, that
     left the first block flush against the image while the second had 26px —
     the asymmetry the review reported (staging #7 / doc A issue 07). With a
     figure present, the first cell gets the same breathing room as its
     sibling, so comparable blocks read with one rhythm. */
  .duo .cell:first-child{border-top:none; padding-top:0;}
  .duo__fig ~ .cols .cell:first-child{padding-top:26px;}

  /* Statement body copy sized for a phone measure. */
  .idea .body{font-size:15px; line-height:1.8;}
  .idea .lead{max-width:100%;}

  /* Privacy copy should not run to the very edge. */
  .privacy .p-in{max-width:100%;}
  .privacy p{font-size:15px;}

  /* Configurator: label + options stack cleanly, stage not too tall. */
  .sn-cfg{padding:16px;}
  .sn-cfg__legend{margin-bottom:10px;}
  .sn-cfg__foot{align-items:stretch;}
  .sn-cfg__meta{text-align:center;}

  /* Caseback engraving comfortable to read. */
  .sn-back__engraving span{font-size:11.5px;}

  /* Closing CTA. */
  .finite .sub{font-size:15px;}
  .finite .stat .n{font-size:26px;}
  .finite .note{font-size:11.5px;}

  /* Footer: .fgrid already stacks at this width; these tune the rest. */
  .fbot{flex-direction:column; align-items:flex-start; gap:14px;}
  .sn-newsletter input{font-size:16px;}   /* no iOS zoom-on-focus */
}

/* ---------------------------------------------------------------
 * Hero cross-fade
 *
 * Client asked for the hero to cycle through two or three product
 * images. Done in CSS so it needs no JavaScript and cannot break if a
 * CDN is slow. Each frame is held, then dissolved — slow and quiet,
 * never a carousel.
 *
 * Two frames = 16s cycle, three = 24s. The base .himg is frame one and
 * stays beneath, so a failed extra image simply never appears.
 * -------------------------------------------------------------- */
.hero .himg--alt{opacity:0;}

/* Two frames: base image + one alternate. 16s cycle. */
.hero .himg--2{animation:sn-hero-a 16s var(--ease) infinite;}
@keyframes sn-hero-a{
  0%,6%   {opacity:0;}
  12%,44% {opacity:1;}
  50%,100%{opacity:0;}
}

/*
 * Three frames: 24s cycle split into thirds. When a third frame exists the
 * second must run on the three-frame timing instead, or the two would overlap
 * — hence the sibling selector rather than a second animation on the same
 * element.
 */
.hero:has(.himg--3) .himg--2{animation:sn-hero-b 24s var(--ease) infinite;}
@keyframes sn-hero-b{
  0%,4%   {opacity:0;}
  10%,29% {opacity:1;}
  35%,100%{opacity:0;}
}
.hero .himg--3{animation:sn-hero-c 24s var(--ease) infinite;}
@keyframes sn-hero-c{
  0%,37%  {opacity:0;}
  43%,62% {opacity:1;}
  68%,100%{opacity:0;}
}

@media (prefers-reduced-motion:reduce){
  .hero .himg--alt{animation:none !important; opacity:0 !important;}
}

/* ---------------------------------------------------------------
 * Two Systems — optional photograph + paper treatment
 *
 * Client brief: present the movement and Lightning side by side with
 * the caseback photo, using the same white presentation as the full
 * specification section.
 * -------------------------------------------------------------- */
.duo__fig{
  margin:0 0 clamp(40px,5vh,68px);
  border:1px solid var(--hair); background:#000;
  aspect-ratio:16/9; overflow:hidden;
}
.duo__fig img{width:100%; height:100%; object-fit:cover; display:block;}
@media (max-width:640px){.duo__fig{aspect-ratio:4/3;}}

/* Paper variant: mirrors .spec so the two read as one system. */
.duo--paper{background:var(--paper); color:var(--ink);}
.duo--paper .sechead .num-idx{color:var(--paper-dim);}
.duo--paper .sechead .num-idx b{color:var(--ink);}
.duo--paper .sechead .label{color:var(--paper-dim);}
.duo--paper .sechead .rule{background:rgba(26,24,21,0.14);}
.duo--paper h2{color:var(--ink);}
.duo--paper .duo__fig{border-color:rgba(26,24,21,0.14);}
.duo--paper .cols{background:rgba(26,24,21,0.14); border-color:rgba(26,24,21,0.14);}
.duo--paper .cell{background:var(--paper);}
.duo--paper .cell:hover{background:#E7E4DD;}
.duo--paper .cell .k{color:var(--paper-dim);}
.duo--paper .cell .k::before{background:var(--paper-dim);}
.duo--paper .cell h3{color:var(--ink);}
.duo--paper .cell p{color:#4A463F;}
/* The base rule hardcodes #E9E7E1 on `.foot p`, which is invisible on paper.
   Target the paragraph itself, not just the wrapper. */
.duo--paper .foot p,
.duo--paper .foot em{color:var(--ink);}

/* ---------------------------------------------------------------
 * Full-bleed band with a numbered head
 *
 * .privacy centres its .wrap with flex. Once a section head is added
 * the head and the copy must stack, with the head pinned to the top of
 * the band rather than floating mid-image.
 * -------------------------------------------------------------- */
.privacy .wrap{position:relative; z-index:2; width:100%;}
.privacy .sechead{margin-bottom:clamp(48px,9vh,120px);}
.privacy .sechead .num-idx{color:rgba(255,255,255,0.62);}
.privacy .sechead .num-idx b{color:#fff;}
.privacy .sechead .label{color:rgba(255,255,255,0.5);}
/* UX review issue 01 / staging #3 and #6: over a FULL-BLEED photograph this
   rule ran edge to edge straight across the watch case, reading as a scratch
   on the print.
   ⚠ It is also the flex SPACER (`.rule{flex:1}`) that holds the section number
   apart from the right-hand label. My first attempt used `display:none`, which
   removed it from layout too and made "02 · The Answer" collide with
   "SN 2140". So it stays in the row and only stops being VISIBLE. */
.privacy .sechead .rule{background:transparent;}
/* A faint shadow lifts the labels off a highlight without a slab of scrim. */
.privacy .sechead .num-idx,
.privacy .sechead .label{text-shadow:0 1px 18px rgba(0,0,0,0.85);}
/* the copy keeps its own measure inside the now-full-width wrap */
.privacy .p-in{position:relative; z-index:2; max-width:44ch;}
@media (max-width:900px){
  .privacy .sechead{margin-bottom:36px;}
  .privacy .p-in{max-width:100%;}
}

/* ---------------------------------------------------------------
 * Statement sections — measure and rhythm
 *
 * The Question ran to five short lines jammed against the left edge
 * with the whole right half empty, and a large dead gap underneath
 * because the block padding assumed a headline plus body copy.
 *
 * A wider measure lets the sentence breathe across the column, and
 * the bottom padding tightens when there is no body paragraph.
 * -------------------------------------------------------------- */
.idea .lead{max-width:30ch;}

/* A statement with no body copy is a single gesture: it should not
   carry the same trailing space as a section with a paragraph. */
.idea .lead:last-child{margin-bottom:0;}
section.block.idea:has(.lead:last-child){
  padding-top:clamp(100px,13vh,170px);
  padding-bottom:clamp(100px,13vh,170px);
}

@media (max-width:900px){ .idea .lead{max-width:24ch;} }
@media (max-width:560px){ .idea .lead{max-width:100%;} }

/* ---------------------------------------------------------------
 * Full-bleed band — headline measure
 *
 * `.p-in` carried a single 44ch measure for the whole column. That is a
 * body-copy measure: applied to a 74px headline it forced "The watch is
 * / not the / starting / point." onto four cramped lines in a narrow
 * gutter. The headline needs its own, much wider measure; the paragraph
 * keeps the readable one.
 * -------------------------------------------------------------- */
.privacy .p-in{max-width:min(52vw, 760px);}
.privacy h2{max-width:15ch;}
.privacy p{max-width:46ch;}

@media (max-width:1100px){
  .privacy .p-in{max-width:min(64vw, 660px);}
  .privacy h2{max-width:16ch;}
}
@media (max-width:900px){
  .privacy .p-in{max-width:100%;}
  .privacy h2,
  .privacy p{max-width:100%;}
}

/* ---------------------------------------------------------------
 * Two Systems — headline measure and figure crop
 *
 * `.duo .top` was 20ch, which broke "Two systems." mid-word ("system/s.")
 * at the display size. And the caseback figure was cropped 16:9 with
 * object-fit:cover, cutting off the engraving that is the whole reason
 * the photograph is there.
 * -------------------------------------------------------------- */
/*
 * `ch` is relative to the element's OWN font-size. `.top` is a plain div at
 * body size, so 26ch resolved to ~231px and still broke the display headline
 * mid-word. Size the wrapper in absolute terms and let the h2 hold the
 * character measure, which is where the display font-size actually applies.
 */
.duo .top{max-width:min(46vw, 640px);}
.duo h2{max-width:12ch;}

/* Show the whole caseback rather than a crop of it. */
/*
 * The caseback render is PORTRAIT (1200x1600). Forcing it into a landscape
 * frame either crops the engraving away or letterboxes it into a stripe.
 * Give the figure a portrait-leaning frame, centre it, and cap its height so
 * it never dominates the section.
 */
/*
 * Full width, matching the two-column grid directly beneath it — a narrow
 * left-aligned panel above full-width columns reads as a mistake. The
 * portrait render is centred inside a landscape band so the caseback sits in
 * the middle of the composition with black either side, which suits the
 * clair-obscur direction rather than fighting it.
 */
.duo__fig{
  /* The frame takes the IMAGE's own ratio, supplied per-figure as --fig-ar
     from the intrinsic file size.

     It used to be a fixed 21:9 for every figure. That band was chosen to stop
     the PORTRAIT renders (1200x1600) running to ~740px each and making the
     page 15,700px long — a real problem, and `contain` did keep them whole.
     But the same band is wrong for the LANDSCAPE studio shots (1600x1066):
     3:2 inside 21:9 shrinks the photograph to about half the frame width and
     leaves black voids either side, which is why the Adjustment section read
     as a mostly-empty box with a small watch adrift in it.

     Matching the image means neither shape is letterboxed — there is no
     unused frame to leave a void, in either axis. `max-height` still bounds
     the portraits so the page-length problem cannot return; a portrait simply
     narrows (via the width cap below) instead of being boxed. */
  aspect-ratio:var(--fig-ar, 21/9);
  max-height:min(56vh,520px);
  /* With a height cap and a matched ratio the frame must be free to narrow,
     or the capped height would reintroduce side voids on the portraits. */
  width:auto;
  max-width:100%;
  margin:0 auto clamp(40px,5vh,68px);
  /* No background: with the frame matched to the image there is no unused
     area for a black plate to show through, and a visible box around every
     photograph is the "page of boxes" fault the client already flagged. */
  background:none;
  /* The earlier .duo__fig block (16:9, "border:1px solid var(--hair)") is
     still in the cascade and its border is what drew the outline around each
     photograph. Cleared here rather than edited there, because that block is
     duplicated further up the file and patching one copy silently loses to
     the next. */
  border:0;
  /* Restores what my earlier override dropped. `.imgrise img` scales to 1.08
     for the reveal, so without this the image spills past the frame and gets
     clipped through the engraving — which looked like a bad crop. */
  overflow:hidden;
}
/* `contain` must beat the earlier `cover` on .duo__fig img — same specificity,
   so this has to stay later in the file. The portrait caseback then sits whole
   and centred in the band instead of being cropped through the engraving. */
/*
 * `height:100%` was resolving against an auto-height figure (the height comes
 * from aspect-ratio, not an explicit value), so the image kept its natural
 * 4:3 portrait height and overflowed. Pinning it to the frame with absolute
 * positioning makes object-fit:contain actually do its job.
 */
/*
 * `.elementor img{height:auto}` ships in Elementor's own stylesheet and loads
 * AFTER the theme, so a plain `.duo__fig img{height:100%}` loses to it and the
 * image kept its natural portrait height — overflowing the frame and clipping
 * the engraving. Matching Elementor's specificity fixes it without !important.
 */
.duo__fig{position:relative;}
.elementor .duo__fig img,
.duo__fig img{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:contain; object-position:center center;
}
@media (max-width:640px){
  /* Phones keep the image's own ratio too — forcing 4:3 here would re-create
     exactly the letterboxing this change removes. The 4/3 fallback now only
     applies to a figure with no measurable size, replacing the 21:9 default,
     which on a 390px screen would be a slit barely 165px tall. Portraits are
     allowed their full height on a phone: the screen is narrow, so a 3:4
     image is only ~470px and does not run away. */
  .duo__fig{aspect-ratio:var(--fig-ar, 4/3); max-height:none;}
}
@media (max-width:640px){
  .duo .top,
  .duo h2{max-width:100%;}
}

/* ---------------------------------------------------------------
 * Elementor's `.elementor img{height:auto}` override
 *
 * Elementor's stylesheet loads AFTER the theme, so every figure that
 * relies on `height:100%` to fill an aspect-ratio frame silently lost
 * that rule: the image kept its natural height, overflowed the frame,
 * and was clipped. That affected the craft rows, the caseback figure
 * and the film — this is why several sections looked mis-cropped.
 *
 * Matching Elementor's specificity restores the intended behaviour
 * without resorting to !important.
 * -------------------------------------------------------------- */
.elementor .cr-fig img{width:100%; height:100%; object-fit:contain;}
.elementor .sn-back__fig img{width:100%; height:100%; object-fit:cover; display:block;}
.elementor .founders figure img{width:100%; height:100%; object-fit:cover; object-position:center 52%;}
.elementor .sn-film__video,
.elementor .sn-film__still{width:100%; height:100%; object-fit:cover; display:block;}
.elementor .sn-review__media img{width:100%; height:100%; object-fit:cover;}

/* ---------------------------------------------------------------
 * Hero type underlay
 *
 * The three slides frame the watch differently, so a single scrim
 * cannot guarantee legibility on all of them — on the front-on dial
 * the headline was sitting directly on bright metal.
 *
 * This is a soft pool of shade anchored to the TEXT COLUMN itself, so
 * the copy always has its own ground regardless of what is behind it.
 * Feathered and off-centre so it never reads as a box.
 * -------------------------------------------------------------- */
.hero .h-in{position:relative;}
.hero .h-in::before{
  content:"";
  position:absolute;
  /* generous bleed so the edges dissolve well outside the type */
  inset:-14vh -18vw -14vh -22vw;
  z-index:-1;
  pointer-events:none;
  background:radial-gradient(58% 52% at 62% 50%,
    rgba(11,10,9,0.82) 0%,
    rgba(11,10,9,0.62) 42%,
    rgba(11,10,9,0.28) 66%,
    transparent 82%);
}
@media (max-width:900px){
  /* Stacked layout: the copy sits low, so the pool follows it down. */
  .hero .h-in::before{
    inset:-10vh -30vw -6vh -30vw;
    background:radial-gradient(70% 46% at 50% 72%,
      rgba(11,10,9,0.86) 0%,
      rgba(11,10,9,0.62) 46%,
      transparent 80%);
  }
}

/* ---------------------------------------------------------------
 * Per-slide framing on mobile
 *
 * Desktop focal points are set per slide in the widget (editable), so
 * no CSS override is needed there. On a stacked layout the copy sits
 * beneath the image, so every slide centres its subject instead.
 * -------------------------------------------------------------- */
@media (max-width:900px){
  .home .hero .hslide{background-position:50% 34% !important;}
}

/* ===============================================================
 * MOTION & MATERIAL — v2.3
 *
 * The reveals were technically firing but too faint to register:
 * 20px of travel and 5px of blur over 1.2s reads as "nothing
 * happened" on a dark page. These are stronger, slower and staggered,
 * which is what makes motion feel expensive rather than busy.
 * =============================================================== */

/* --- Reveal: more travel, longer settle ------------------------ */
.js .rise{
  opacity:0;
  transform:translateY(34px);
  filter:blur(8px);
  transition:
    opacity   1.5s var(--ease),
    transform 1.5s var(--ease),
    filter    1.5s var(--ease);
}
.js .rise.in{opacity:1; transform:none; filter:blur(0);}

/* Stagger inside a section so elements arrive in sequence. */
.js .rise.d1{transition-delay:.14s;}
.js .rise.d2{transition-delay:.28s;}
.js .rise.d3{transition-delay:.42s;}

/* Hairlines draw rather than appear. */
.js .draw{transform:scaleX(0); transform-origin:left; transition:transform 1.7s var(--ease);}
.js .draw.in{transform:scaleX(1);}

/* Images settle from a soft scale AND resolve from blur. */
.js .imgrise img{
  transform:scale(1.10);
  filter:blur(10px);
  opacity:0;
  transition:transform 2.2s var(--ease), filter 1.7s var(--ease), opacity 1.5s var(--ease);
}
.js .imgrise.in img{transform:scale(1); filter:blur(0); opacity:1;}

/* --- Glass morphism -------------------------------------------- */
/*
 * Frosted panels, used where content sits over photography or needs to
 * feel like a physical surface. Kept restrained: low saturation, a
 * single hairline, and a soft inner highlight along the top edge —
 * light catching a bevel, which is the Charte's language.
 */
.sn-glass,
.sn-cfg,
.sn-checkout__review,
.sn-back__engraving,
.sn-form-note{
  background:linear-gradient(180deg, rgba(255,255,255,0.055), rgba(255,255,255,0.018));
  -webkit-backdrop-filter:blur(18px) saturate(120%);
          backdrop-filter:blur(18px) saturate(120%);
  border:1px solid rgba(255,255,255,0.10);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.14),      /* top-edge highlight */
    0 20px 60px rgba(0,0,0,0.42);
}

/* On the paper sections the glass inverts to a light frosted panel. */
.duo--paper .cell{
  background:linear-gradient(180deg, rgba(255,255,255,0.55), rgba(255,255,255,0.18));
  -webkit-backdrop-filter:blur(14px) saturate(115%);
          backdrop-filter:blur(14px) saturate(115%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.6);
}
/* The earlier flat hover colour would drop the frost on hover — keep the
   material and just lift it. */
.duo--paper .cell:hover{
  background:linear-gradient(180deg, rgba(255,255,255,0.72), rgba(255,255,255,0.30));
}

/* Configurator options as small glass chips.
 *
 * SAFARI FIX: these previously used backdrop-filter:blur(10px). In Safari a
 * backdrop-filter promotes the element to its own compositing layer, and that
 * layer can swallow pointer events on the element and its children — so the
 * model and strap buttons never received a click. Chrome and Firefox composite
 * this differently, which is why the configurator worked there and not in
 * Safari (macOS and iOS), exactly as the client reported.
 *
 * The chips keep their glassiness through a translucent gradient instead,
 * which composites normally and stays clickable everywhere. Do not reintroduce
 * backdrop-filter on an interactive element.
 */
.sn-cfg__opt{
  background:linear-gradient(180deg, rgba(255,255,255,0.07), rgba(255,255,255,0.03));
  transition:
    background   .5s var(--ease),
    border-color .5s var(--ease),
    color        .5s var(--ease),
    transform    .5s var(--ease);
}
.sn-cfg__opt:hover{transform:translateY(-1px); background:rgba(255,255,255,0.07);}
.sn-cfg__opt.is-active{
  background:rgba(255,255,255,0.10);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.18);
}

/* --- Considered hover on the primary action -------------------- */
/* ---------------------------------------------------------------
 * The primary button
 *
 * REGRESSION FIX: this rule used to live in woocommerce.css. When that
 * stylesheet was scoped to commerce pages for performance, every CTA on
 * the homepage, SN 2140, Story and Technology silently lost its styling
 * and rendered as bare text.
 *
 * The button is not commerce-specific, so it belongs here. The
 * WooCommerce selectors stay in woocommerce.css alongside it.
 * -------------------------------------------------------------- */
.sn-cta{
  display:inline-block;
  font-family:"Oswald",sans-serif; font-weight:400;
  font-size:12px; letter-spacing:0.22em; text-transform:uppercase;
  color:var(--fg); background:none;
  border:1px solid rgba(255,255,255,0.42); border-radius:0;
  padding:20px 54px; line-height:1; text-shadow:none;
  cursor:pointer; -webkit-appearance:none; appearance:none;
  text-decoration:none;
  position:relative; overflow:hidden;
  transition:background .5s var(--ease), color .5s var(--ease), border-color .5s var(--ease);
}
.sn-cta:hover{background:var(--fg); color:var(--black); border-color:var(--fg);}
.sn-cta::after{
  /* a slow sheen crossing the button, not a flash */
  content:"";
  position:absolute; top:0; bottom:0; left:-60%;
  width:45%;
  background:linear-gradient(100deg, transparent, rgba(255,255,255,0.18), transparent);
  transform:translateX(0);
  transition:transform 1.1s var(--ease);
  pointer-events:none;
}
.sn-cta:hover::after{transform:translateX(340%);}

/* --- Reduced motion: material stays, movement goes ------------- */
@media (prefers-reduced-motion:reduce){
  .js .rise,
  .js .draw,
  .js .imgrise img{
    opacity:1 !important;
    transform:none !important;
    filter:none !important;
    transition:none !important;
  }
  .sn-cta::after{display:none;}
}

/* backdrop-filter is GPU-expensive when it spans a large area over a
   photograph. The configurator panel covers most of the viewport on a
   phone, so drop the frost there and keep a plain tint. */
@media (max-width:640px){
  .sn-cfg,
  .sn-checkout__review{
    -webkit-backdrop-filter:none;
            backdrop-filter:none;
    background:rgba(20,19,17,0.72);
  }
}

/* ===============================================================
 * CONFIGURATOR — full-page treatment (v2.4)
 *
 * Client: "make this take the whole page with white space and
 * animation so it feels subtle luxury."
 *
 * The section previously sat in a bordered card with tight padding,
 * which made it read as a widget rather than a product display. This
 * gives it the full viewport, removes the frame entirely, and lets the
 * watch sit in open space with the controls as a quiet column beside it.
 *
 * Appended last so it supersedes the earlier stacked definitions.
 * =============================================================== */
.sn-configure{
  min-height:100vh;
  display:flex;
  flex-direction:column;
  justify-content:center;
  padding-top:clamp(90px,11vh,150px);
  padding-bottom:clamp(90px,11vh,150px);
  background:
    radial-gradient(120% 80% at 50% 42%, rgba(255,255,255,0.045) 0%, transparent 62%),
    var(--black);
}

/* No card. The section itself is the surface. */
.sn-cfg{
  display:grid;
  grid-template-columns:1.35fr 0.65fr;
  gap:clamp(48px,7vw,130px);
  align-items:center;
  margin-top:clamp(48px,7vh,90px);
  border:none;
  background:none;
  padding:0;
  -webkit-backdrop-filter:none;
          backdrop-filter:none;
  box-shadow:none;
}

/* The watch floats in open space, lit from beneath. */
.sn-cfg__stage{
  aspect-ratio:1/1;
  border:none;
  background:none;
  overflow:visible;
  position:relative;
}
.sn-cfg__stage::before{
  /* a soft pool of light the object sits in — no hard frame */
  content:"";
  position:absolute; inset:6% 4% 2%;
  border-radius:50%;
  background:radial-gradient(ellipse at 50% 58%,
    rgba(255,255,255,0.085) 0%,
    rgba(255,255,255,0.03) 42%,
    transparent 72%);
  filter:blur(28px);
  pointer-events:none;
}
.sn-cfg__img{
  position:relative; z-index:1;
  width:100%; height:100%;
  object-fit:contain;
  /* the swap is a slow dissolve with a breath of scale */
  transition:opacity .55s var(--ease), transform .9s var(--ease), filter .55s var(--ease);
}
.sn-cfg__img.is-swapping{opacity:0; transform:scale(1.03); filter:blur(6px);}

/* Controls: a quiet column, generously spaced. */
.sn-cfg__panel{
  display:flex; flex-direction:column;
  gap:clamp(30px,4.2vh,48px);
  padding-left:clamp(0px,1.5vw,24px);
}
.sn-cfg__legend{
  display:block; margin-bottom:16px;
  /* 11px is the audit floor. Tracked uppercase reads larger than its px value,
     but 10px measured under it, so it is raised rather than exempted. */
  font-size:11px; letter-spacing:0.26em;
}
.sn-cfg__opts{gap:10px;}
.sn-cfg__opt{padding:13px 18px; font-size:13.5px;}

.sn-cfg__foot{
  padding-top:clamp(26px,3.4vh,40px);
  border-top:1px solid var(--hair);
  gap:16px;
}
.sn-cfg__meta{font-size:11px; letter-spacing:0.06em;}

/* Photography note sits under the object, not over it. */
.sn-cfg__note{
  position:static; margin-top:20px;
  padding:0; background:none; border:none;
  font-size:11.5px; line-height:1.7; color:var(--faint);
  text-align:center;
}

@media (max-width:900px){
  .sn-configure{min-height:0; padding-top:clamp(70px,9vh,110px); padding-bottom:clamp(70px,9vh,110px);}
  .sn-cfg{grid-template-columns:1fr; gap:44px; margin-top:40px;}
  /* 3/4 matches the source art (1200x1600). This is the LAST 900px rule in the
     file, so it is the one that actually applies — earlier copies were being
     overridden from here. */
  .sn-cfg__stage{aspect-ratio:3/4;}
  .sn-cfg__panel{padding-left:0;}
}

/* The media column wraps the stage and its note. */
.sn-cfg__media{display:flex; flex-direction:column;}

/* ===============================================================
 * 01 · THE QUESTION — full-page treatment (v2.5)
 *
 * Client: "make this take the whole page with white space and
 * animation so it feels subtle luxury."
 *
 * A single question, alone on a full viewport. The brief asked for
 * this section to be "extremely concise", and giving one sentence the
 * whole screen is what makes it land — the restraint IS the design.
 *
 * Scoped to `.idea` sections that carry ONLY a headline, so statement
 * sections that also have body copy keep their normal rhythm.
 * =============================================================== */
section.block.idea:has(.lead:last-child){
  min-height:100vh;
  display:flex;
  flex-direction:column;
  justify-content:center;
  padding-top:clamp(90px,12vh,160px);
  padding-bottom:clamp(90px,12vh,160px);
  position:relative;
  /* the faintest pool of light behind the words, off-centre */
  background:
    radial-gradient(70% 55% at 34% 46%, rgba(255,255,255,0.038) 0%, transparent 68%),
    var(--black);
}

/* The question sits large and open, with room around it. */
section.block.idea:has(.lead:last-child) .lead{
  max-width:24ch;
  font-size:clamp(30px,4.6vw,72px);
  line-height:1.12;
  letter-spacing:-0.03em;
  margin-bottom:0;
}

/* The section head floats well above, so the question stands alone. */
section.block.idea:has(.lead:last-child) .sechead{
  margin-bottom:clamp(60px,11vh,150px);
}

/*
 * Motion: the question resolves rather than arrives.
 *
 * A slower, longer settle than the site default — this is the one
 * sentence the whole page turns on, so it earns a moment. The blur
 * clearing is what reads as "expensive"; the travel is deliberately
 * small so nothing lurches.
 */
.js section.block.idea:has(.lead:last-child) .lead{
  opacity:0;
  transform:translateY(26px);
  filter:blur(12px);
  transition:
    opacity   2.1s var(--ease),
    transform 2.1s var(--ease),
    filter    2.1s var(--ease);
}
.js section.block.idea:has(.lead:last-child) .lead.in{
  opacity:1; transform:none; filter:blur(0);
}

/* The hairline draws slowly across, ahead of the words. */
.js section.block.idea:has(.lead:last-child) .draw{
  transition:transform 2.4s var(--ease);
}

@media (max-width:900px){
  section.block.idea:has(.lead:last-child){
    min-height:0;
    padding-top:clamp(70px,9vh,110px);
    padding-bottom:clamp(70px,9vh,110px);
  }
  section.block.idea:has(.lead:last-child) .lead{max-width:100%; font-size:clamp(26px,6.6vw,40px);}
  section.block.idea:has(.lead:last-child) .sechead{margin-bottom:clamp(36px,6vh,60px);}
}

@media (prefers-reduced-motion:reduce){
  .js section.block.idea:has(.lead:last-child) .lead{
    opacity:1 !important; transform:none !important; filter:none !important; transition:none !important;
  }
}

/* ---------------------------------------------------------------
 * Configurator: hiding an unavailable dial
 *
 * `.sn-cfg__opt{display:inline-flex}` is a class selector, so it beats
 * the browser's own `[hidden]{display:none}` (an attribute selector of
 * lower weight). The result: selecting Anthracite PVD left "Light grey"
 * on screen and still marked active, offering a combination that does
 * not exist.
 *
 * This makes the hidden state actually win.
 * -------------------------------------------------------------- */
.sn-cfg__opt[hidden]{display:none !important;}

/*
 * A finish with only one dial has no choice to present. The glass-chip
 * styling added later overrode the earlier `is-single` rule, so the lone
 * option still looked like a button. Restate it after the chip styles so
 * it reads as a statement of fact rather than something to click.
 */
.sn-cfg__group.is-single .sn-cfg__opt,
.sn-cfg__group.is-single .sn-cfg__opt.is-active,
.sn-cfg__group.is-single .sn-cfg__opt:hover{
  background:none;
  -webkit-backdrop-filter:none;
          backdrop-filter:none;
  border-color:transparent;
  box-shadow:none;
  transform:none;
  padding-left:0;
  cursor:default;
  color:var(--dim);
}

/* ===============================================================
 * FULL-SCREEN SECTIONS (v2.6)
 *
 * Every homepage section now occupies the viewport, so the page reads
 * as a sequence of held moments rather than a continuous scroll. This
 * is what makes the pacing feel deliberate: one idea per screen.
 *
 * `min-height` rather than `height`, so a section that genuinely needs
 * more room (the configurator on a short laptop) can still grow.
 * =============================================================== */
.home section.block,
.home section.privacy,
.home section.moment{
  min-height:100vh;
  display:flex;
  flex-direction:column;
  justify-content:center;
}

/* The full-bleed bands centre their content in the viewport. */
.home .privacy{
  height:auto;
  padding-top:clamp(80px,10vh,140px);
  padding-bottom:clamp(80px,10vh,140px);
}

/* Two Systems needs breathing room around the caseback + columns. */
.home .duo{
  padding-top:clamp(80px,10vh,140px);
  padding-bottom:clamp(80px,10vh,140px);
}

/* The closing CTA is a full screen of its own: the last thing seen. */
.home .finite{
  padding-top:clamp(80px,10vh,150px);
  padding-bottom:clamp(80px,10vh,150px);
}

/*
 * Below ~900px a full viewport per section becomes a lot of scrolling
 * on a small screen, so sections size to their content again.
 */
@media (max-width:900px){
  .home section.block,
  .home section.privacy,
  .home section.moment{
    min-height:0;
    display:block;
  }
  .home .privacy,
  .home .duo,
  .home .finite{
    padding-top:clamp(70px,9vh,110px);
    padding-bottom:clamp(70px,9vh,110px);
  }
}

/* Short viewports (laptops, landscape tablets): never trap content. */
@media (max-height:760px) and (min-width:901px){
  .home section.block,
  .home section.privacy,
  .home section.moment{min-height:0; padding-top:96px; padding-bottom:96px;}
}

/* ===============================================================
 * CONFIGURATOR — three models, one strap toggle (v2.7)
 *
 * Replaces the Case + Dial pair. The range is a fixed list of three
 * watches, so it is presented as one: each row names the model and
 * states its dial and supplied strap, and no impossible combination
 * can be selected.
 * =============================================================== */

/* The model list stacks; each row is a full-width card. */
.sn-cfg__opts--stack{flex-direction:column; align-items:stretch; gap:10px;}

.sn-cfg__model{
  display:flex; align-items:center; gap:16px;
  width:100%; text-align:left;
  padding:16px 20px;
}
.sn-cfg__modeltxt{display:flex; flex-direction:column; gap:4px; min-width:0;}
.sn-cfg__modelname{
  font-size:14.5px; line-height:1.25; color:var(--fg);
  letter-spacing:0.01em;
}
.sn-cfg__modelmeta{
  font-family:"Oswald",sans-serif;
  font-size:10px; letter-spacing:0.16em; text-transform:uppercase;
  color:var(--faint); line-height:1.4;
}
.sn-cfg__model.is-active .sn-cfg__modelmeta{color:var(--dim);}

/* Chips show the real case + dial pairing at a glance. */
.sn-cfg__sw--ti-light{background:linear-gradient(135deg,#cfcbc4 0 50%,#b3afa8 50% 100%);}
.sn-cfg__sw--ti-dark{background:linear-gradient(135deg,#cfcbc4 0 50%,#2b2a28 50% 100%);}
.sn-cfg__sw--pvd-dark{background:linear-gradient(135deg,#3a3936 0 50%,#141312 50% 100%);}
.sn-cfg__model .sn-cfg__sw{
  width:22px; height:22px; flex:none;
  border:1px solid rgba(255,255,255,0.16);
}

@media (max-width:560px){
  .sn-cfg__model{padding:14px 16px; gap:13px;}
  .sn-cfg__modelname{font-size:14px;}
}

/* ------------------------------------------------------------------
   Hero: tall photographs.

   A portrait frame in a landscape hero would be cover-scaled and cropped
   to its middle, which reads as an over-zoomed close-up. Where the image
   is deliberately tall and right for the page (a worn-on-the-wrist story
   frame, say), the widget marks it .hslide--tall and it is composed to
   the right of the copy at its own proportions instead of filling.
   ------------------------------------------------------------------ */
.hero .hslide--tall{
  background-size:contain !important;
  background-position:right center !important;
}

/* Keep the subject clear of the headline column on wide screens. */
@media (min-width:900px){
  .hero .hslide--tall{
    background-size:auto 100% !important;
    background-position:78% center !important;
  }
}

/* On narrow screens there is no side room, so return to a top-weighted
   cover crop: the subject sits above the copy rather than behind it. */
@media (max-width:899px){
  .hero .hslide--tall{
    background-size:cover !important;
    background-position:center 22% !important;
  }
}

/* ------------------------------------------------------------------
   Configurator buttons: keep the whole chip clickable.

   The buttons wrap <span> children (swatch, name, meta). Some engines
   retarget a click to the child, and a child with its own layer can
   also intercept the press. Neither can happen if the children are
   transparent to the pointer: the <button> always receives the event.
   ------------------------------------------------------------------ */
.sn-cfg__opt > *{pointer-events:none;}
.sn-cfg__opt{cursor:pointer; -webkit-tap-highlight-color:transparent; touch-action:manipulation;}

/* ==================================================================
   Configurator layout — Safari grid blowout fix.

   REPORTED: on Safari (macOS and iOS) the configurator section rendered
   as an empty black area with no visible controls, while Chrome and
   Firefox were correct. A diagnostic on the client's own machine showed
   the buttons WERE in the DOM (5 options, 3 models parsed, handler
   fired) but taps landed on .sn-cfg__img — i.e. the photograph was
   covering the area where the panel should be. A layout failure, not a
   scripting one.

   CAUSE: a grid item's default min-width/min-height is `auto`, not 0,
   so it refuses to shrink below its content. .sn-cfg__stage carries
   aspect-ratio:1/1, and Safari resolves that square against the track
   differently from Chrome — the media column grows far beyond its
   share, pushing .sn-cfg__panel out of view.

   FIX: let the grid items shrink, and bound the stage explicitly so the
   aspect-ratio box can never dictate the row height. Written so the
   result is identical in every engine rather than special-cased.
   ================================================================== */
.sn-cfg > *{min-width:0; min-height:0;}

.sn-cfg__media{
  min-width:0;
  max-width:100%;
}

.sn-cfg__stage{
  width:100%;
  max-width:100%;
  /* Bound the square so it can never drive an unbounded row height. */
  max-height:min(76vh, 720px);
  margin-inline:auto;
}

/* The photograph fits the stage rather than defining it. */
.sn-cfg__img{
  max-width:100%;
  max-height:100%;
  object-fit:contain;
}

/* The controls must never be pushed out of the viewport. */
.sn-cfg__panel{min-width:0;}

/* Single column below the breakpoint: image first, controls beneath. */
@media (max-width:900px){
  /* Single column here, so the stage cannot squeeze the panel sideways
     and needs no HEIGHT cap. Bound the WIDTH instead — that is the
     dimension aspect-ratio keys off, so a width cap scales the whole
     frame rather than cropping it, and the two can never disagree the
     way a vh cap does. On a 900px tablet this keeps the watch to a
     560px-wide plate instead of a 1147px-tall wall. See the fuller note
     at "Configurator: controls reachable sooner" below. */
  .sn-cfg__stage{max-height:none; max-width:min(100%, 560px);}
}

/* ==================================================================
   RESPONSIVE AUDIT FIXES (3.8.0)

   Findings from rendering every page at 390 / 768 / 1024 / 1440 and
   measuring the DOM, then reviewing per-section captures. Each block
   names the defect it closes.
   ================================================================== */

/* --- Full-bleed band copy width ----------------------------------
   The band copy is pinned to one side so it never sits on the subject.
   That pin was an inline max-width:min(38vw,520px), which at 390px is a
   150px column: headlines broke into six lines and body copy into
   ribbons. Wide screens keep the pin; below 900px the copy takes the
   full measure and reads left-to-right, with the photograph behind. */
.privacy .p-in--left,
.privacy .p-in--right{
  max-width:min(100%, 600px);
  margin-right:auto;
  text-align:left;
}
@media (min-width:901px){
  .privacy .p-in--left{
    max-width:min(38vw, 520px);
    margin-right:auto;
  }
  .privacy .p-in--right{
    max-width:min(38vw, 520px);
    margin-left:auto;
    margin-right:0;
    text-align:right;
  }
  /* Staging review #2: the BODY COPY was inheriting text-align:right, so three
     lines of prose ran ragged down the LEFT edge and trailed off under the
     headline — hard to read, and it never lined up with the headline's right
     edge because the two have different measures.
     The headline keeps its right alignment (it is display type, two short
     lines, and the alignment is the composition). The paragraph is set ragged-
     right like every other paragraph on the site, and pinned to the same right
     edge as the headline so the block reads as one column. */
  .privacy .p-in--right p{
    text-align:left;
    max-width:38ch;
    margin-left:auto;
    margin-right:0;
  }
}

/* --- Two-systems cells: divider slab on stacked layouts ------------
   .duo .cols draws its hairline dividers as a 1px gap over a hairline
   coloured background. Below 900px the gap grows to 38px, so the divider
   colour became a 38px grey bar between the stacked cells (visible on
   Home, Story and Technology). Stacked cells now use real borders and
   no gap, so there is nothing to show through. */
@media (max-width:900px){
  .duo .cols{
    gap:0;
    background:transparent;
    border:1px solid var(--hair);
  }
  /* Cells already carry a border-top at this width (line ~1019); reset it so
     the wrapper border and the divider are never doubled. */
  .duo .cols .cell{border-top:none;}
  .duo .cols .cell + .cell{border-top:1px solid var(--hair);}
  .duo--paper .cols{border-color:rgba(26,24,21,0.14);}
  .duo--paper .cols .cell + .cell{border-top-color:rgba(26,24,21,0.14);}
}

/* --- Specification plate: annotations overflowing the plate --------
   On mobile the six annotations become static rows INSIDE .plate, but
   .plate kept a fixed aspect-ratio sized to the photograph, so the rows
   spilled below its box and the caption (whose margin is measured from
   the plate's edge) printed straight across "36.5 x 40.7 mm" and "43 g".
   The plate now grows with its content; the photograph carries the
   aspect ratio itself. */
@media (max-width:900px){
  .spec .plate{aspect-ratio:auto; display:block;}
  .spec .plate img{
    aspect-ratio:16/10;
    width:100%; height:auto;
    display:block;
    margin-bottom:6px;
  }
  .spec .caption{margin-top:40px;}
}

/* --- Legibility floors ---------------------------------------------
   Measured at 10px or below on every viewport. Labels stay in the
   letterspaced Oswald register, one step larger. */
.sn-cfg__modelmeta{font-size:11px;}
.sn-field label{font-size:11px;}
@media (max-width:560px){
  .sn-cfg__modelmeta{font-size:11.5px; letter-spacing:0.14em;}
}
/* The phone bump that used to raise this cue from 9px to 10px is gone: the
   base rule is now 11px at every width, which clears the audit floor. */

/* --- Touch targets -------------------------------------------------
   The logo link measured 120x14 and the desktop nav links 18px tall on
   an iPad in landscape (1024px, where the desktop nav is shown). Hit
   areas are enlarged with padding cancelled by negative margins, so the
   header's visual geometry does not change. */
header#nav > a{
  display:flex; align-items:center;
  padding:14px 0; margin:-14px 0;
}
@media (min-width:901px){
  header nav a{
    display:inline-block;
    padding:13px 0; margin:-13px 0;
  }
}

/* ==================================================================
   MOBILE DESIGN PASS (3.9.0)

   The 3.8.0 audit fixed what was broken on small screens. This pass is
   about what was merely weak. Reviewed screen-by-screen at 390x844:

     - the hero set its headline at 22px, small for the one moment the
       page has to make an impression, and the photograph read as a dark
       patch of case;
     - the photo bands were squat (~350px) and side-lit for desktop, so on
       a phone they became dark boxes with a paragraph and the photograph
       all but vanished;
     - text sections carried desktop-scale padding and 100vh minimums, so
       four lines of copy could occupy a whole screen;
     - the configurator photograph filled a full screen before any control
       appeared;
     - the three availability figures stacked into a tall column;
     - the footer ran to nearly two screens.

   Principles: on a phone the photograph goes ABOVE the words (bottom-lit
   bands), type scales up not down, sections earn their height from content
   rather than viewport units, and utility blocks (stats, footer) compress.
   Desktop and tablet-landscape are untouched: everything here is inside
   max-width queries. `svh` is used so browser chrome never hides a hero's
   bottom edge; `vh` remains as the fallback for older engines.
   ================================================================== */

/* ---- 1. Hero: confident type, legible over any crop ---------------- */
@media (max-width:900px){
  .hero{
    min-height:100vh;
    min-height:100svh;
    align-items:flex-end;
  }
  .hero .wrap{position:relative; z-index:3; padding-bottom:clamp(64px,11vh,96px);}   /* above the ::after light sweep (z 2) */
  /* A bottom-weighted shade so the headline never fights the photograph,
     whatever the crop happens to be on a given phone. */
  .hero::before{
    content:""; position:absolute; left:0; right:0; bottom:0; height:58%;
    background:linear-gradient(180deg, transparent 0%, rgba(11,10,9,0.55) 45%, rgba(11,10,9,0.92) 100%);
    z-index:1; pointer-events:none;
  }
  .hero h1{
    font-size:clamp(30px, 8.6vw, 38px);
    line-height:1.08;
    letter-spacing:-0.025em;
    max-width:100%;
  }
  .hero .cue{bottom:22px;}
}
@media (max-width:560px){
  .hero h1{font-size:clamp(30px, 8.6vw, 36px);}   /* overrides the 22px floor above */
}

/* ---- 2. Photo bands: photograph above, words below ------------------ */
@media (max-width:900px){
  .privacy{
    min-height:72vh;
    min-height:72svh;
    display:flex; align-items:flex-end;
    padding:0 0 clamp(40px,6vh,60px);
  }
  .privacy .wrap{width:100%;}
  /* Keep the horizontal focal point the widget chose; lift the subject
     into the upper half where it is now visible. */
  .privacy .pimg{ background-position-y:30% !important; }
  .privacy .pimg{
    -webkit-mask-image:linear-gradient(180deg, #000 0%, #000 70%, transparent 100%);
            mask-image:linear-gradient(180deg, #000 0%, #000 70%, transparent 100%);
  }
  /* The desktop scrim is side-lit; on a phone the copy sits at the foot,
     so the shade runs bottom-up instead. */
  .privacy .shade{
    background:linear-gradient(180deg, rgba(11,10,9,0.10) 0%, rgba(11,10,9,0.22) 40%, rgba(11,10,9,0.86) 72%, #0B0A09 100%) !important;
  }
  .privacy .sechead{margin-bottom:clamp(140px,26vh,240px);}   /* pushes copy down, keeps the head at the top */
  .privacy h2{font-size:clamp(30px, 8vw, 38px); line-height:1.08;}
  .privacy p{font-size:15.5px; line-height:1.7; margin-top:18px;}
  /* px, not ch: ch would resolve against .p-in's 16px body size (~317px) and split place names. */
  .privacy .p-in--left, .privacy .p-in--right{max-width:min(100%, 600px);}
}

/* ---- 3. Type scale and rhythm ---------------------------------------- */
@media (max-width:900px){
  /* Sections earn their height from content on a phone. */
  main section.block,
  main section.block.idea:has(.lead:last-child),
  main .sn-configure{min-height:0 !important;}

  section.block{padding:clamp(56px,9vh,84px) 0;}
  .sechead{margin-bottom:clamp(30px,5vh,44px);}

  .idea .lead,
  .craft .lead,
  .sn-configure .lead,
  .duo .top h2{
    font-size:clamp(27px, 7.4vw, 34px);
    line-height:1.12;
    letter-spacing:-0.02em;
    max-width:100%;
  }
  .idea .body,
  .cr-txt p,
  .duo .cell p,
  .duo .foot p,
  .finite .sub,
  .sn-contact__intro,
  .sn-cfg__hint{
    font-size:15.5px; line-height:1.7;
  }
  .idea .body{margin-top:22px;}
}

/* ---- 4. Configurator: controls reachable sooner ---------------------- */
@media (max-width:900px){
  .sn-cfg{gap:26px; margin-top:26px;}
  /* NO height cap on phones — this is deliberate.
     The stage is sized by its WIDTH (aspect-ratio:3/4, matching the
     1200x1600 source art), but a vh cap bounds its HEIGHT. The two
     disagree on any short-and-wide phone: the old 50vh resolved to 422px
     against a stage that wanted 467px, so `object-fit:contain` shrank the
     watch and the sticky header ate the top of it. Raising the percentage
     only moves the breakage to a shorter device (62vh still crops a
     667px-tall SE). Below 900px the configurator is already single-column
     with the controls stacked underneath, so an uncapped stage pushes
     nothing off-screen, and `.sn-cfg > *{min-height:0}` above is what
     actually prevents the Safari grid blowout this cap was first added
     for. Let the ratio decide. */
  .sn-cfg__stage{max-height:none;}
  .sn-cfg__panel{gap:22px;}
  .sn-cfg__model{padding:14px 16px;}
}

/* ---- 5. Craft rows: tighter, index beside the heading ---------------- */
@media (max-width:900px){
  .craft-row{gap:20px; margin-bottom:64px;}
  .cr-fig, .craft-row.wide .cr-fig{aspect-ratio:4/3;}
  .cr-txt{display:grid; grid-template-columns:auto 1fr; column-gap:14px; align-items:baseline;}
  .cr-txt .idx{grid-column:1; grid-row:1; margin:0; font-size:11px;}
  .cr-txt h3{grid-column:2; grid-row:1; font-size:clamp(26px,7vw,32px); margin-bottom:12px;}
  .cr-txt p, .cr-txt .kbd{grid-column:2;}
  .cr-txt .kbd{margin-top:16px;}
}

/* ---- 6. Availability figures: one compact row ------------------------ */
@media (max-width:720px){
  .finite .stat{
    grid-template-columns:repeat(3,1fr);
    gap:0; padding:22px 0;
  }
  .finite .stat > div{padding:0 8px; border-left:1px solid var(--hair);}
  .finite .stat > div:first-child{border-left:none; padding-left:0;}
  .finite .stat .n{font-size:clamp(19px, 5.4vw, 24px); letter-spacing:-0.01em;}
  .finite .stat .k{font-size:9.5px; letter-spacing:0.14em; margin-top:8px;}
}

/* ---- 7. Footer: one screen, not two ---------------------------------- */
@media (max-width:900px){
  footer{padding:56px 0 28px;}
  .fgrid{grid-template-columns:1fr 1fr; gap:34px 24px;}
  .fbrand, .fnl{grid-column:1 / -1;}
  .fbrand p{max-width:100%;}
  .fcol li{margin-bottom:9px;}
  .fnl .field{max-width:100%;}
  .fbot{margin-top:40px; padding-top:20px;}
}
@media (max-width:560px){
  .fgrid{grid-template-columns:1fr 1fr;}    /* keeps Explore | Legal side by side (was 1fr) */
}

/* Footer, second trim: brand line and newsletter share a row on phones so
   the whole footer fits one screen. */
@media (max-width:900px){
  footer{padding:48px 0 24px;}
  .fgrid{gap:28px 22px;}
  .fbrand img{width:auto; margin-bottom:14px;}
  .fbrand .swiss{margin-top:10px; line-height:1.7;}
  .fnl p{margin-bottom:10px;}
  .fbot{margin-top:30px; padding-top:16px;}
}

/* =======================================================================
   SINGLE JOURNAL POST
   The index (.jcard/.feat) was styled; the article itself never was, so a
   post rendered as unstyled browser defaults on a black background.

   Measure is the whole job here. Long-form on a dark ground needs a shorter
   line and more leading than the marketing sections, so .prose sets its own
   max-width in ch rather than inheriting the page grid.
   ==================================================================== */

/* --- header ---------------------------------------------------------- */
.ahead{padding:clamp(120px,18vh,190px) 0 clamp(34px,5vh,56px);}
.ahead .back{display:inline-block; margin-bottom:clamp(36px,6vh,64px); color:var(--faint); transition:color .3s var(--ease);}
.ahead .back:hover{color:var(--fg);}
.ahead h1{
  font-weight:300; font-size:clamp(32px,5.2vw,66px); line-height:1.08;
  letter-spacing:-0.03em; max-width:19ch; color:#F1EFEA;
}
.ahead .meta{
  display:flex; align-items:center; flex-wrap:wrap; gap:14px;
  margin-top:clamp(26px,4vh,40px);
  font-family:"Space Mono",monospace; font-size:12px; letter-spacing:0.04em;
  color:var(--faint);
}
.ahead .meta .cat{color:var(--dim);}
.ahead .meta .dot{width:3px; height:3px; border-radius:50%; background:var(--faint); flex:none;}

/* --- hero photograph -------------------------------------------------- */
.ahero{padding:0 0 clamp(48px,7vh,90px);}
.ahero .afig{overflow:hidden;}
.ahero .afig img{display:block; width:100%; height:auto;}

/* --- body ------------------------------------------------------------- */
.abody{padding:0 0 clamp(90px,13vh,160px);}
/* Left-aligned, NOT centred. The article header, the hero photograph and every
   other section on the site share a left edge at the .wrap gutter; centring the
   body alone broke that alignment and left the h1 and its own text starting at
   different x positions.

   SCOPED TO .abody ON PURPOSE. page.php uses .prose too, and Cart and Checkout
   are pages — an unscoped 68ch cap here crushed the whole two-column checkout
   into 605px and collapsed the order summary to one character per line. Only
   the single-post body gets a reading measure. */
.abody .prose{max-width:68ch; margin:0;}
.abody .prose > * + *{margin-top:1.5em;}

.abody .prose p{
  font-size:clamp(15.5px,1.15vw,17.5px); line-height:1.78;
  letter-spacing:0.005em; color:#D8D4CD;
}
/* Opening paragraph carries the weight of a standfirst. */
.abody .prose .lead{
  font-size:clamp(19px,1.75vw,25px); line-height:1.5;
  letter-spacing:-0.01em; color:#F1EFEA;
  margin-bottom:1.9em;
}
.abody .prose h2{
  margin-top:2.4em;
  font-weight:400; font-size:clamp(21px,2vw,29px); line-height:1.22;
  letter-spacing:-0.02em; color:#F1EFEA;
}
.abody .prose h2 + p{margin-top:1.1em;}
.abody .prose h3{
  margin-top:2em;
  font-family:"Oswald",sans-serif; font-weight:400;
  font-size:13px; letter-spacing:0.24em; text-transform:uppercase;
  color:var(--dim);
}
.abody .prose em{font-style:italic;}
.abody .prose strong{font-weight:500; color:#F1EFEA;}

.abody .prose a{
  color:#F1EFEA;
  /* The Charte reserves Bleu Supernova for underlines and fine details —
     this is exactly that case, and the only place it appears in body copy. */
  border-bottom:1px solid #00a8e2;
  padding-bottom:1px;
  transition:border-color .3s var(--ease), color .3s var(--ease);
}
.abody .prose a:hover{border-bottom-color:var(--fg);}

.abody .prose blockquote{
  margin:2.4em 0; padding:0 0 0 clamp(20px,3vw,38px);
  border-left:1px solid rgba(255,255,255,0.22);
}
.abody .prose blockquote p{
  font-size:clamp(19px,1.9vw,27px); line-height:1.4;
  letter-spacing:-0.015em; color:#F1EFEA;
}

.abody .prose ul,.abody .prose ol{padding-left:1.3em;}
.abody .prose li{
  margin-bottom:0.6em;
  font-size:clamp(15.5px,1.15vw,17.5px); line-height:1.78; color:#D8D4CD;
}
.abody .prose li::marker{color:var(--faint);}

.abody .prose img{display:block; width:100%; height:auto; margin:2.6em 0;}
.abody .prose figcaption{
  margin-top:12px;
  font-family:"Space Mono",monospace; font-size:11.5px; color:var(--faint);
}
.abody .prose hr{
  margin:3em 0; border:0; height:1px; background:var(--hair);
}

.page-links{margin-top:2.6em;}

@media (max-width:900px){
  .ahead{padding:clamp(96px,14vh,130px) 0 30px;}
  .ahead h1{max-width:100%;}
  .ahead .meta{gap:10px; font-size:11.5px;}
  /* Full width on phones: a 68ch measure would leave the text in a column
     narrower than the gutters allow. */
  .abody .prose{max-width:100%;}
  .abody .prose > * + *{margin-top:1.4em;}
  .abody .prose h2{margin-top:2em;}
  .abody .prose blockquote{margin:2em 0; padding-left:18px;}
}

/* ==================================================================
   SCROLL OFFSET UNDER THE STICKY HEADER (4.12.4)

   The header is `position:fixed`, but nothing told the scroll container
   about it, so every in-page landing — an anchor link, a
   `scrollIntoView`, a browser restoring a scroll position — put its
   target underneath the header. On the configurator this ate the top of
   the watch: the stage was sized correctly (measurements showed the
   image filling it exactly, no letterboxing) yet the dial was still
   hidden, because the fault was WHERE the page stopped, not how big the
   image was.

   `scroll-padding-top` on the scroll container fixes all of them at once
   and is inert when nothing is scrolling to an anchor. The value clears
   the header in its SCROLLED state (16px padding + the 25px logo cap =
   ~57px), which is the state it is always in after a scroll, plus room
   so the subject is not flush against the chrome.
   ================================================================== */
html{scroll-padding-top:88px;}

/* Desktop chrome is taller: 26px padding + a 25px logo, and the header
   only collapses once the user is already moving. */
@media (min-width:901px){
  html{scroll-padding-top:104px;}
}

/* ==================================================================
   MENU OPEN: KEEP THE LOGO AND CLOSE BUTTON ON TOP (4.12.5)

   `#nav-menu` is a SIBLING of the logo and the toggle inside <header>,
   not an overlay on the page. So the header's own `z-index:100` decides
   nothing here — it stacks the header against the document, while these
   three children stack against EACH OTHER. The nav carried z-index:99
   and the toggle only 2, so the full-screen menu painted straight over
   the close button and the logo: the menu opened with no visible way
   out. `document.elementFromPoint()` at the toggle's centre returned
   NAV.is-open, which is the check that catches this — the button was
   still "visible" by every computed style.

   Both controls are lifted above the nav. The logo also needs an
   explicit position, since `position:static` ignores z-index entirely.
   ================================================================== */
body.nav-open header > a,
header:has(#nav-menu.is-open) > a{
  position:relative;
  z-index:101;
}

.nav-toggle{
  position:relative;
  z-index:101;
}

/* ==================================================================
   FIGURE CENTRING (4.13.1)

   `.duo__fig` is now width:auto so the frame can match its image's
   ratio, but an auto-width block still sits flush LEFT.

   Plain `.duo__fig{margin-inline:auto}` LOSES. Elementor ships
   `.elementor .elementor-widget:not(.elementor-widget-text-editor)
   :not(.elementor-widget-theme-post-content) figure{margin:0}` in its
   own stylesheet, which loads AFTER the theme — the same trap already
   documented above for `.elementor img{height:auto}`.

   COUNT THE :not()s. Each one contributes a class-level weight, so that
   selector is (0,4,1) — not the (0,2,1) it looks like. My first attempt
   at `.elementor .elementor-widget figure.duo__fig` was (0,3,1) and
   still lost, silently. The selector below is (0,6,1).

   The bare class is kept for the Elementor-free case (the widget also
   renders outside a page built with Elementor).
   ================================================================== */
.elementor .elementor-widget .duo figure.duo__fig.imgrise,
.duo__fig{
  margin-left:auto;
  margin-right:auto;
  /* Elementor's `margin:0` zeroes the bottom spacing too, so restate it
     here or the cells crowd straight up against the photograph. */
  margin-bottom:clamp(40px,5vh,68px);
}

/* ==================================================================
   SOCIAL ROW (4.15.0)

   Official profiles in the footer's "Stay Close" column, under the
   newsletter field. Text labels rather than icons: the Charte allows
   three type styles and no icon set, and four brand glyphs would be the
   loudest thing in a deliberately quiet footer.
   ================================================================== */
.sn-social{
  list-style:none;
  margin:18px 0 0;
  padding:0;
  display:flex;
  flex-wrap:wrap;
  gap:8px 18px;
}
.sn-social a{
  font-size:12px;
  letter-spacing:0.08em;
  text-transform:uppercase;
  color:var(--muted, #878787);
  text-decoration:none;
  border-bottom:1px solid transparent;
  padding-bottom:2px;
  transition:color .3s var(--ease, ease), border-color .3s var(--ease, ease);
}
.sn-social a:hover,
.sn-social a:focus-visible{
  color:#fff;
  /* Bleu Supernova is sanctioned for fine details only — a hairline
     underline is exactly that usage. */
  border-bottom-color:#00a8e2;
}

/* ==================================================================
   INSTITUTIONAL MARKS (4.15.0)

   Story > The Network. Three logos of very different proportion (a
   vertical Vaud lockup, a wide Trust Valley mark, a tall awards
   roundel), so each gets its own height and they are balanced by
   VISUAL WEIGHT rather than forced to one dimension.

   Muted by default and brought up on hover: they are supporting
   credentials, not the subject of the page.
   ================================================================== */
.sn-insts{
  list-style:none;
  margin:clamp(40px,5vh,64px) 0 0;
  padding:0;
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:center;
  gap:clamp(32px,5vw,72px);
}
.elementor .elementor-widget .sn-inst img,
.sn-inst img{
  display:block;
  width:auto;
  /* Elementor ships `.elementor img{height:auto}` and loads after the theme,
     so a bare `.sn-inst img{height:…}` loses and every mark renders at its
     natural size. Matched to Elementor's specificity — same trap as
     `.duo__fig` (see FIGURE CENTRING above). */
  height:48px;
  opacity:0.62;
  transition:opacity .4s var(--ease, ease);
}
.elementor .elementor-widget .sn-inst.is-tall img,
.sn-inst.is-tall img{height:86px;}   /* vertical Vaud lockup */
.elementor .elementor-widget .sn-inst.is-mid img,
.sn-inst.is-mid  img{height:74px;}   /* awards roundel, STISS */
/* Swiss Bitcoin Pay is a long horizontal wordmark: at a shared height it
   would run three times the width of its neighbours. */
.elementor .elementor-widget .sn-inst.is-wide img,
.sn-inst.is-wide img{height:26px;}
.sn-inst img:hover{opacity:1;}

@media (max-width:640px){
  .sn-insts{gap:34px;}
  .elementor .elementor-widget .sn-inst img,
  .sn-inst img{height:40px;}
  .elementor .elementor-widget .sn-inst.is-tall img,
  .sn-inst.is-tall img{height:70px;}
  .elementor .elementor-widget .sn-inst.is-mid img,
  .sn-inst.is-mid  img{height:60px;}
  .elementor .elementor-widget .sn-inst.is-wide img,
  .sn-inst.is-wide img{height:22px;}
}

/* ==================================================================
   PRE-ORDER ACKNOWLEDGEMENT (4.16.0)

   A required checkbox above the submit button. Deliberately plain and
   legible rather than styled down: this is a legal acknowledgement and
   must not read as fine print the buyer can skim past.
   ================================================================== */
.sn-ack{
  margin:26px 0 22px;
  padding:18px 20px;
  border:1px solid var(--hair, rgba(255,255,255,0.14));
  background:rgba(255,255,255,0.02);
}
.sn-ack__label{
  display:flex;
  align-items:flex-start;
  gap:12px;
  cursor:pointer;
}
.sn-ack input[type="checkbox"]{
  flex:0 0 auto;
  width:17px;
  height:17px;
  margin:2px 0 0;
  accent-color:#00a8e2;   /* Charte: blue for fine detail only */
  cursor:pointer;
}
.sn-ack__text{
  font-size:13px;
  line-height:1.65;
  color:var(--muted, #878787);
  /* Legal text must read as sentences. A checkout label rule elsewhere
     uppercases this span, which makes a 60-word acknowledgement close to
     unreadable — and an unreadable consent notice is not consent. Stated
     explicitly, with the letter-spacing reset that travels with it. */
  text-transform:none;
  letter-spacing:normal;
  font-family:"Inter","Helvetica Neue",Helvetica,Arial,sans-serif;
}
.sn-ack__text a{
  color:inherit;
  text-decoration:underline;
  text-underline-offset:2px;
  white-space:nowrap;
  margin-left:4px;
}
.sn-ack__text a:hover{color:#fff;}

/* An unchecked box after a failed submit must be obvious. */
.sn-ack:has(input:invalid){border-color:rgba(255,255,255,0.3);}

@media (max-width:640px){
  .sn-ack{padding:16px;}
  .sn-ack__text{font-size:12.5px;}
}

/* ==================================================================
   HEADER SUBSCRIBE LINK (4.16.0)

   Client asked for the newsletter to be more prominent than the footer
   alone. Deliberately a quiet link rather than a button: it sits beside
   the primary nav and must not compete with Reserve.
   ================================================================== */
.nav-subscribe{
  /* Matches the other nav items exactly (Oswald, 12px, 0.16em, uppercase,
     var(--dim)) so it reads as part of the menu rather than a bolted-on
     button. Client asked for it aligned with the rest and WITHOUT the
     underline it previously carried. */
  font-family:"Oswald",sans-serif;
  font-size:12px;
  letter-spacing:0.16em;
  text-transform:uppercase;
  color:var(--dim);
  text-decoration:none;
  border-bottom:0;
  transition:color .3s;
  white-space:nowrap;
  /* The sibling nav links carry 13px padding top AND bottom (a 44px box).
     Zeroing the bottom made this box 31px, and the flex row centres boxes —
     so a shorter box sits 6px lower than its neighbours. Matching the padding
     is what actually aligns it, not align-self. */
  padding-top:13px;
  padding-bottom:13px;
}
.nav-subscribe:hover,
.nav-subscribe:focus-visible{
  color:var(--fg);
  border-bottom:0;
}

/* The ACTIVE page carries the underline instead — one clear signal of where
   you are, rather than a permanent rule under a call to action.

   The rule is drawn with a pseudo-element rather than a border, because a
   border adds 1px + padding to the box and pushed the active item (and only
   the active item) 4px down out of line with its neighbours. This keeps every
   item on the same baseline. */
header nav a{position:relative;}
header nav a.here{color:var(--fg);}
header nav a.here::after{
  content:"";
  position:absolute;
  left:0; right:0; bottom:-5px;
  height:1px;
  background:currentColor;
}

@media (max-width:900px){
  .nav-subscribe{
    display:block;
    margin-top:26px;
    font-size:13px;
  }
}

/* ==================================================================
   JOURNAL HOLDING STATE (4.16.0)

   The Journal launches before it is populated. This must read as
   intentional, so it is a composed block with the signup, not a bare
   line of apology.
   ================================================================== */
.jempty{
  max-width:58ch;
  margin:clamp(40px,7vh,86px) 0 0;
}
.jempty__lead{
  font-size:clamp(20px,2.4vw,26px);
  line-height:1.35;
  color:#fff;
  margin:0 0 16px;
}
.jempty__sub{
  font-size:15px;
  line-height:1.7;
  color:var(--muted, #878787);
  margin:0 0 30px;
}


/* Visually hidden, still read aloud. Previously supplied only by Elementor's
   and WooCommerce's stylesheets — defined here so the skip link, form labels
   and icon-button text never depend on a plugin being loaded. */
.screen-reader-text{
  border:0; clip:rect(1px,1px,1px,1px); clip-path:inset(50%);
  height:1px; width:1px; margin:-1px; padding:0; overflow:hidden;
  position:absolute !important; word-wrap:normal !important;
}
.screen-reader-text:focus{
  clip:auto !important; clip-path:none; height:auto; width:auto; margin:0;
  display:block; left:16px; top:16px; z-index:100000;
  padding:14px 22px; background:var(--panel); color:var(--fg); text-decoration:none;
}
