/* shared: collection grid, detail page, site header, cart button and cart dialog */
:root{--pill:#1c1e21;--rule:#26292d;--ink-3:#5c6167;
      --gutter:clamp(20px,4vw,56px);      /* the least room anything leaves at the window edge... */
      --column:min(1200px,100% - 2 * var(--gutter));  /* ...and the one measure a page's content is
                                             set on: header, sections, footer. The hero is the
                                             exception and stays full width, to the gutter; so do
                                             backgrounds and the worn photography. */
      --header-h:60px;                    /* the floating header bar itself... */
      --header-top:clamp(10px,1.8vh,20px);/* ...how far it floats clear of the top... */
      --bar-pad:24px;                     /* ...and the padding it holds its content in by */
      --header-space:calc(var(--header-h) + var(--header-top) * 2);   /* ...and the room a page leaves it */
      --field:rgba(255,255,255,.04);   /* what a form field is filled with */
      --on-ink:#0e0f10;                /* text on a button filled with --ink */
      --bad:#ffb4b4}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
/* every chip, tab, button, field and link, on every page */
:focus-visible{outline:2px solid var(--ink);outline-offset:4px;border-radius:999px}
/* an author display rule would otherwise beat the browser's own [hidden] */
[hidden]{display:none!important}
a{color:inherit;text-decoration:none}
/* the Contact link in the nav glides down the page rather than jumping */
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
/* and stops clear of the floating header, instead of parking the heading underneath it */
html{scroll-padding-top:var(--header-space)}

/* ---------- collection (3 x 3) ---------- */
.collection{width:var(--column);margin-inline:auto}
.collection h2{font-size:clamp(28px,3.4vw,44px);font-weight:500;letter-spacing:-.02em;max-width:24ch}
.collection .lede{color:var(--ink-2);margin-top:10px;max-width:48ch;line-height:1.5}
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(12px,2vw,28px);margin-top:6vh}
.card{display:flex;flex-direction:column;align-items:center;gap:14px;padding:clamp(18px,2.5vw,32px) 16px 22px;border-radius:28px;
      text-align:center;transition:background .18s,transform .18s}
.card:hover,.card:focus-visible{background:rgba(255,255,255,.05);transform:translateY(-2px)}
.card img{height:clamp(160px,22vw,300px);width:auto;display:block;filter:drop-shadow(0 22px 28px rgba(0,0,0,.6))}
.card .name{font-size:15px;font-weight:500;letter-spacing:.1em;margin-top:6px}
.card .meta{font-size:13px;color:var(--ink-2);display:flex;gap:14px}
.card.in-cart .meta .price{color:var(--ink)}
.card.in-cart .meta .price::before{content:"✓ "}
/* Sold out: the render steps back and the price line says so instead */
.card.sold-out img{opacity:.42}
.card.sold-out .meta .price{color:var(--ink-2);letter-spacing:.04em}

/* ---------- between sections ---------- */
/* Every section arrives the same way: a band of the page's own ground with the section's name set
   on a hairline across the column. The interval is the whole gap — a section on this same ground
   adds no top padding of its own. See docs/adr/0002. */
.interval{position:relative;display:grid;place-items:center;height:18vh}
.interval::before{content:'';position:absolute;left:50%;translate:-50%;height:1px;background:var(--rule);
                  width:var(--column)}
.interval span{position:relative;padding:0 22px;background:var(--bg);color:var(--ink-2);
               font-size:12px;font-weight:500;letter-spacing:.1em;text-transform:uppercase}

/* ---------- handover ---------- */
/* A section's name arrives with twice the room above it, and that second measure closes as it
   comes up the window — which is what the hero's boundary does, and the only thing the other two
   were missing. An interval is 18vh with its name on the middle, so the room above the name is
   9vh: the extra is another of those, held open above the interval and taken straight back below
   it, so the page is no longer for it. js/handover.js sets `--closed` from 0 to 1 as the interval
   rises, and the block slides up by what is still to close. Nothing is pinned, nothing covered.

   Until the script has run, and for anyone who asked for reduced motion, `--closed` is 1: the
   extra is already closed and every interval is the 18vh it always was. */
.handover{--extra:9vh;margin-top:var(--extra);margin-bottom:calc(-1 * var(--extra));
          transform:translate3d(0,calc(-1 * var(--extra) * var(--closed,1)),0)}
@media (prefers-reduced-motion:reduce){.handover{--closed:1}}

/* ---------- contact ---------- */
/* The one light thing on the site: a full-width sheet of paper to write on, closing the page.
   The palette is the page's own, inverted here, so everything inside follows without knowing.
   The bottom padding is deep on purpose — it is the page's last space, and its floor keeps Send
   clear of the cart bar, which takes about 96px off the bottom of the screen when it is out. */
.contact{--ink:#14161a;--ink-2:#5f646b;--ink-3:#aeb4bb;--rule:#e3e6ea;
         --field:rgba(15,17,20,.035);--on-ink:#ffffff;--bad:#b3261e;
         color:var(--ink);background:#fff;text-align:center;
         padding:clamp(56px,9vh,110px) var(--gutter) clamp(128px,16vh,180px)}
.contact h2{font-size:clamp(28px,3.4vw,44px);font-weight:500;letter-spacing:-.02em;max-width:24ch;margin-inline:auto}
.contact .lede{color:var(--ink-2);margin-top:10px;max-width:52ch;line-height:1.5;margin-inline:auto}
#contact-form{display:grid;grid-template-columns:1fr 1fr;gap:18px 24px;margin-top:5vh;max-width:760px;
              margin-inline:auto;text-align:left}
.field{display:flex;flex-direction:column;gap:8px}
.field.wide{grid-column:1 / -1}
.field label{font-size:13px;color:var(--ink-2);letter-spacing:.04em}
.field input,.field textarea{font:inherit;font-size:15px;color:var(--ink);background:var(--field);
  border:1px solid var(--rule);border-radius:14px;padding:12px 14px;resize:vertical;transition:border-color .18s,background .18s}
.field input:hover,.field textarea:hover{border-color:var(--ink-3)}
.field input:focus-visible,.field textarea:focus-visible{outline:2px solid var(--ink);outline-offset:2px;border-radius:14px}
/* the hidden field: off screen rather than display:none, which bots skip */
.honeypot{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form-actions{grid-column:1 / -1;display:flex;align-items:center;justify-content:center;gap:18px;flex-wrap:wrap}
.form-status{font-size:14px;line-height:1.5;color:var(--ink-2);max-width:44ch}
/* with nothing to say it would still hold its gap, and push Send off centre */
.form-status:empty{display:none}
.form-status.ok{color:var(--ink)}
.form-status.bad{color:var(--bad)}

/* ---------- tabs ---------- */
.tabs{display:flex;gap:8px;margin-top:5vh;border-bottom:1px solid var(--rule)}
.tab{padding:12px 4px;margin-bottom:-1px;font-size:14px;color:var(--ink-2);border-bottom:1px solid transparent;
     letter-spacing:.04em;transition:color .18s,border-color .18s}
.tab+.tab{margin-left:24px}
.tab:hover{color:var(--ink)}
.tab[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--ink)}
.tab:focus-visible{outline:2px solid var(--ink);outline-offset:4px;border-radius:4px}

/* ---------- straps ---------- */
.straps{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(12px,2vw,28px);margin-top:6vh}
.strap-card{display:flex;flex-direction:column;align-items:center;gap:12px;padding:clamp(18px,2.5vw,32px) 16px 22px;
            border-radius:28px;text-align:center;background:rgba(255,255,255,.03);transition:background .18s}
.strap-card:hover{background:rgba(255,255,255,.06)}
.strap-card img{height:clamp(190px,24vw,340px);width:auto;display:block;filter:drop-shadow(0 22px 28px rgba(0,0,0,.6))}
.strap-card .name{font-size:15px;font-weight:500;letter-spacing:.06em;margin-top:4px}
/* two cards can show the same leather, so the finish is named, and wears the same swatch the
   Case chips use rather than asking the visitor to tell rose from brushed at thumbnail size */
.strap-card .buckle{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--ink-2)}
.strap-card .buckle .sw{width:13px;height:13px;border-radius:50%;flex:none;box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.strap-card .meta{font-size:13px;color:var(--ink-2);display:flex;gap:10px;align-items:center;min-height:20px}
.strap-card.in-cart .meta .price{color:var(--ink)}
.strap-card.in-cart .meta .price::before{content:"✓ "}
.strap-card.sold-out img{opacity:.42}
.strap-card .add{margin-top:4px}
/* the buckle in each photograph is a styling choice, not a thing to pick, so the note sits
   under the row rather than beside a control */
.straps-note{margin-top:28px;text-align:center;font-size:13px;color:var(--ink-3);line-height:1.6}
.btn.small{padding:10px 20px;font-size:14px}

/* ---------- detail ---------- */
.detail{width:var(--column);margin-inline:auto;padding:2vh 0 10vh}
.back{font-size:14px;color:var(--ink-2)}.back:hover{color:var(--ink)}
.detail-grid{display:grid;grid-template-columns:1.1fr 1fr;gap:clamp(24px,5vw,80px);align-items:start;margin-top:3vh}
/* The watch sits at the top of its column, so the first screen shows all of it rather than its
   middle, and it stays put while the options and the spare straps scroll past it. */
.product-stage{display:grid;place-items:start center;position:sticky;top:var(--header-space)}
.product-stage img{max-height:min(72vh,calc(100svh - var(--header-space) - 8vh));width:auto;max-width:100%;
                   filter:drop-shadow(0 40px 60px rgba(0,0,0,.7));transition:opacity .25s}
.product-stage img.swap{opacity:0}
.panel h1{font-size:clamp(36px,5vw,72px);font-weight:500;letter-spacing:-.025em;line-height:.95}
.panel .sub{color:var(--ink-2);margin-top:12px;line-height:1.5;max-width:40ch}
.opt{margin-top:36px}
.opt h3{font-size:13px;font-weight:500;color:var(--ink-2);letter-spacing:.06em;display:flex;justify-content:space-between}
.opt h3 span{color:var(--ink);font-weight:400;letter-spacing:0}
.chips{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px}
.chip{display:inline-flex;align-items:center;gap:10px;padding:10px 16px 10px 10px;border:1px solid var(--rule);border-radius:999px;font-size:14px;transition:border-color .18s,background .18s}
.chip:hover{border-color:var(--ink-3)}
.chip[aria-pressed="true"]{border-color:var(--ink);background:rgba(255,255,255,.06)}
.chip .sw{width:22px;height:22px;border-radius:50%;flex:none;box-shadow:inset 0 0 0 1px rgba(255,255,255,.12)}
.chip[hidden]{display:none}
.buy{margin-top:40px;display:flex;align-items:center;gap:20px}
.price-big{font-size:28px;font-weight:500;letter-spacing:-.01em}
.btn{display:inline-flex;align-items:center;justify-content:center;padding:14px 24px;border-radius:999px;font-size:15px;font-weight:500;
     border:1px solid var(--ink);background:var(--ink);color:var(--on-ink);transition:transform .12s,opacity .18s}
.btn:hover{opacity:.92}.btn:active{transform:scale(.98)}
.btn[disabled]{opacity:.35;cursor:default;transform:none}
.btn[disabled]:hover{opacity:.35}
.specs{margin-top:44px;display:grid;grid-template-columns:1fr 1fr;gap:10px 24px;font-size:14px;color:var(--ink-2);line-height:1.6;border-top:1px solid var(--rule);padding-top:20px}
.specs b{color:var(--ink);font-weight:500}

/* ---------- spare strap row (detail page) ---------- */
/* Set apart from the configurator above it: its own rule, heading and note,
   so adding a spare Strap never reads as changing the Watch's own Strap. */
.spare{margin-top:40px;padding-top:24px;border-top:1px solid var(--rule)}
.spare h3{font-size:13px;font-weight:500;color:var(--ink-2);letter-spacing:.06em;text-transform:uppercase}
.spare-note{font-size:13px;color:var(--ink-3);margin-top:6px;max-width:44ch;line-height:1.5}
.spare-row{margin-top:18px;gap:10px}
.spare-row .strap-card{padding:14px 8px 16px;gap:8px;border-radius:20px}
.spare-row .strap-card img{height:clamp(110px,12vw,168px)}
.spare-row .strap-card .name{font-size:13px;letter-spacing:.04em;margin-top:0}
.spare-row .strap-card .buckle{font-size:12px;gap:6px}
.spare-row .strap-card .buckle .sw{width:11px;height:11px}
.spare-row .strap-card .meta{font-size:12px}
.spare-row .strap-card .add{padding:8px 16px;font-size:13px}

/* ---------- site header ---------- */
/* A bar that floats clear of the page rather than sitting on its edge — the same pill the Cart used
   to be, moved to the top and given the nav. On the home page it waits above the window: the hero
   carries its own nav for the first screen, and shop.js drops this one in once the hero has been
   scrolled past. Pages without a hero show it from the start and indent by var(--header-space).
   It is centred with a translate, so every transform here has to carry the -50% along with it.
   The bar is the column plus its own padding on each side, so what is *inside* it — the mark, the
   links, the Cart — lands on the same column as the page and the footer, rather than the bar's
   padding pushing it in. The second term only bites on a narrow window, where it keeps the ends
   off the screen edge at the cost of a few pixels of that alignment. */
.site-header{position:fixed;top:var(--header-top);left:50%;transform:translateX(-50%);z-index:30;
             /* the hairline below counts toward the inset under border-box, so it is in here too */
             width:min(calc(var(--column) + 2 * var(--bar-pad) + 2px),100% - 16px);
             height:var(--header-h);border-radius:999px;
             display:flex;align-items:center;justify-content:space-between;gap:24px;
             padding:0 var(--bar-pad);font-size:14px;
             background:rgba(28,30,33,.86);border:1px solid rgba(255,255,255,.08);
             backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
             box-shadow:0 20px 50px rgba(0,0,0,.6);transition:opacity .4s,transform .4s}
.site-header.hidden{opacity:0;pointer-events:none;transform:translate(-50%,-20px)}
.site-header .brand{display:flex;align-items:center;color:var(--ink)}
.site-header .brand .mark{display:block;height:26px;width:auto}
.site-nav{display:flex;align-items:center;gap:clamp(14px,2.2vw,28px)}

/* the cart button: the icon, the word, and the count when there is one */
.cart-button{display:inline-flex;align-items:center;gap:9px;padding:8px 14px;border-radius:999px;line-height:1;
             border:1px solid rgba(255,255,255,.16);transition:background .15s,border-color .15s}
.cart-button:hover{border-color:var(--ink-2);background:rgba(255,255,255,.06)}
.cart-icon{width:17px;height:17px;flex:none}
.cart-count{min-width:20px;height:20px;padding:0 6px;border-radius:999px;background:var(--ink);color:var(--on-ink);
            font-size:11px;font-weight:600;display:grid;place-items:center}
/* adding happens away from the header, so the button nods to say it arrived */
@keyframes cart-bump{0%{transform:none}35%{transform:scale(1.11)}100%{transform:none}}
.cart-button.bump{animation:cart-bump .34s ease}

/* ---------- cart dialog ---------- */
/* A real <dialog>: the browser gives the focus trap, Escape, and an inert page behind for free.
   `display` may only be set for the open state — styling the element itself would defeat the
   UA's own `dialog:not([open]){display:none}` and leave the cart sitting on the page. */
/* `margin:auto` is what centres a modal in the browser's own stylesheet, and every page here
   resets margins with a `*` rule, so it has to be said again. */
.cart-dialog{margin:auto;width:min(560px,calc(100vw - 32px));max-height:min(78vh,760px);padding:0;color:var(--ink);
             background:var(--pill);border:1px solid rgba(255,255,255,.09);border-radius:24px;
             box-shadow:0 30px 80px rgba(0,0,0,.6)}
.cart-dialog[open]{display:flex;flex-direction:column}
.cart-dialog::backdrop{background:rgba(0,0,0,.62);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.cart-head{display:flex;align-items:center;justify-content:space-between;gap:16px;
           padding:20px clamp(16px,3vw,24px) 16px;border-bottom:1px solid var(--rule)}
.cart-head h2{font-size:12px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2)}
.cart-close{width:34px;height:34px;margin-right:-6px;border-radius:50%;display:grid;place-items:center;color:var(--ink-2)}
.cart-close svg{width:18px;height:18px}
.cart-close:hover{color:var(--ink);background:rgba(255,255,255,.06)}
.cart-lines{flex:1;overflow-y:auto;padding:0 clamp(16px,3vw,24px)}
.cart-line{display:grid;grid-template-columns:54px 1fr auto auto;align-items:center;gap:clamp(10px,2vw,16px);padding:16px 0}
.cart-line+.cart-line{border-top:1px solid var(--rule)}
.cart-line img{width:54px;height:54px;object-fit:contain}
.line-name{display:flex;flex-direction:column;gap:4px;min-width:0}
.line-name .name{font-size:14px;font-weight:500}
.line-name .unit{font-size:12px;color:var(--ink-2)}
/* the stepper: one control, so it reads as a quantity rather than two loose buttons */
.line-qty{display:flex;align-items:center;gap:2px;border:1px solid var(--rule);border-radius:999px;padding:2px}
.line-qty button{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;font-size:15px;color:var(--ink-2)}
.line-qty button:hover:not([disabled]){color:var(--ink);background:rgba(255,255,255,.07)}
.line-qty button[disabled]{opacity:.3;cursor:default}
.line-qty .qty{min-width:22px;text-align:center;font-size:13px;font-variant-numeric:tabular-nums}
.line-total{font-size:14px;font-weight:500;font-variant-numeric:tabular-nums;text-align:right;min-width:62px}
.cart-empty{padding:40px 0 44px;text-align:center;color:var(--ink-2);font-size:14px}
.cart-foot{padding:16px clamp(16px,3vw,24px) clamp(16px,3vw,22px);border-top:1px solid var(--rule)}
.cart-sum{display:flex;align-items:baseline;justify-content:space-between;gap:16px}
.cart-sum span{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2)}
.cart-sum b{font-size:26px;font-weight:500;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.cart-foot .checkout{width:100%;margin-top:14px;padding:14px 26px}
.cart-foot .checkout[disabled]{opacity:.35;cursor:default}
.cart-note{margin-top:10px;text-align:center;font-size:12px;color:var(--ink-3);line-height:1.5}
/* checkout trouble is said where the Checkout button is, not somewhere up the dialog */
.cart-error{margin-bottom:14px;padding:10px 14px;border-radius:14px;
            background:rgba(40,22,22,.94);border:1px solid rgba(255,140,140,.28);color:#ffd9d9;
            font-size:13px;line-height:1.45}

@media (max-width:900px){
  .grid{grid-template-columns:repeat(2,1fr)}
  .straps{grid-template-columns:repeat(3,1fr);gap:12px}
  .strap-card{padding:16px 10px 18px}
  .detail-grid{grid-template-columns:1fr}.product-stage{position:static}.product-stage img{max-height:52vh}
}
@media (max-width:520px){
  #contact-form{grid-template-columns:1fr}
  .grid{grid-template-columns:1fr}
  .straps{grid-template-columns:1fr}
  /* the spare row stays three across: the cards are small and it is a side offer, not the main event */
  .spare-row{grid-template-columns:repeat(3,1fr);gap:8px}
  .spare-row .strap-card{padding:12px 6px 14px}
  .spare-row .strap-card .name{font-size:12px}
  .spare-row .strap-card .add{padding:7px 10px;font-size:12px}
  /* the word goes, the icon and the count stay: the header has to hold a brand and three links too */
  .cart-label{display:none}
  .cart-button{gap:7px;padding:8px 11px}
  .site-nav{gap:14px}
  /* the line total drops to its own row rather than squeezing the name to nothing */
  .cart-line{grid-template-columns:44px 1fr auto;row-gap:8px}
  .cart-line img{width:44px;height:44px}
  .line-total{grid-column:2/4;text-align:right}
}
/* Phone-width header: brand, three links and the cart have to share one row, so everything gives
   a little. Below this the row is as tight as it goes without dropping a link behind a menu. */
@media (max-width:420px){
  .site-header{--bar-pad:14px;gap:10px}
  .site-header .brand .mark{height:22px}
  .site-nav{gap:11px;font-size:13px}
  .cart-button{gap:6px;padding:7px 9px}
  .cart-count{min-width:18px;height:18px;padding:0 5px}
}
@media (prefers-reduced-motion:reduce){
  .card,.chip,.site-header,.cart-button,.product-stage img,.strap-card,.tab{transition:none}

  .cart-button.bump{animation:none}
}

/* ---------- footer ---------- */
/* Black, whatever the page above it is doing, and signed off with the wordmark at the size
   it deserves. No <nav> in here on purpose: every page styles the bare element for its header. */
.site-footer{background:#000;color:var(--ink-2);padding-top:clamp(56px,9vh,96px);font-size:14px}
/* one column for all three bands, so the wordmark lines up with the links above it */
.foot-top,.foot-bar,.foot-wordmark{width:var(--column);margin-inline:auto}
.foot-top{display:grid;grid-template-columns:minmax(240px,1fr) auto;gap:clamp(32px,6vw,80px)}
.foot-brand .mark{display:block;width:96px;height:auto}
.foot-brand p{margin-top:18px;max-width:34ch;line-height:1.6}
.social{display:flex;gap:12px;margin-top:24px;padding:0;list-style:none}
.social a{display:grid;place-items:center;width:38px;height:38px;border:1px solid var(--rule);border-radius:50%;
          color:var(--ink-2);transition:color .18s,border-color .18s}
.social a:hover{color:var(--ink);border-color:var(--ink-2)}
.social svg{width:17px;height:17px}
.foot-links{display:grid;grid-template-columns:repeat(2,minmax(120px,auto));gap:clamp(28px,5vw,72px)}
.foot-links h2{font-size:12px;font-weight:500;color:var(--ink);letter-spacing:.1em;text-transform:uppercase}
.foot-links ul{display:grid;gap:11px;margin:18px 0 0;padding:0;list-style:none}
.foot-links a{color:var(--ink-2);transition:color .18s}
.foot-links a:hover{color:var(--ink)}
.foot-bar{margin-top:clamp(40px,7vh,72px);padding-top:22px;border-top:1px solid var(--rule);
          display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;font-size:13px}
/* the wordmark, with its bottom fifth cropped away: 267.15 / (54.63 x 0.8) */
.foot-wordmark{margin-top:clamp(40px,7vh,84px);overflow:hidden;line-height:0;aspect-ratio:6.11}
.foot-wordmark img{display:block;width:100%;height:auto}
@media (max-width:760px){
  .foot-top{grid-template-columns:1fr;gap:40px}
  .foot-links{grid-template-columns:repeat(2,1fr)}
}
