/* Reign Wala, The Everywhere Bag: homepage.
   Mobile first. Base styles are the 390px layout; 560 / 760 / 900 / 1200 / 1440 / 1800 add.
   One warm-white ground from the first photograph to the last. The only saturated colour is leather.
   What moves: the opening settles in; below it, things arrive once as they come into view (headings rise,
   photographs develop, a section's hairline draws, the two display lines rise word by word: css/motion.css);
   a bag lifts under the hand. Nothing replays and nothing is tied to the scroll position. */

:root {
  --page: #f7f5f1;
  --paper: #fffefb;
  --ink: #111a3b;
  --soft: #474d66;
  --quiet: #6b6f84;
  --plum: #614051;
  --sand: #d3b59c;
  --gold: #c2a063;
  --line: rgba(17, 26, 59, 0.14);
  --line-soft: rgba(17, 26, 59, 0.08);
  --line-strong: rgba(17, 26, 59, 0.38);
  --max: 1180px;
  --pad: 20px;
  --mast: 62px;
  --tick: 30px;
  /* colour: navy is the ink; powder and dusty are the two bands' grounds */
  --navy: #111a3b;
  --powder: #dde3ee;
  --dusty: #89b0b5;
  --peach: #ffdeb2;
  --on-navy: #f7f5f1;
  --on-navy-soft: rgba(247, 245, 241, 0.72);
  --line-navy: rgba(247, 245, 241, 0.16);
  /* type: one scale. 11 label / 13 small / 15 body (16 from 900) / 18 lead / 21 subhead, then names and headings */
  --t-label: 11px; --t-small: 13px; --t-body: 15px; --t-lead: 18px; --t-h3: 21px;
  --t-input: 16px;                              /* form fields never go under 16px, or phones zoom in */
  --t-name: clamp(23px, 2vw, 29px);             /* a bag's name on its card */
  --t-h2: clamp(31px, 8.4vw, 38px);
  --t-h2-s: clamp(30px, 3vw, 42px);             /* a heading set in a narrow rail or beside other words */
  --t-say: clamp(27px, 7.2vw, 34px);            /* the large statements: What's a wala, the footer sign-off */
  --t-sub: clamp(22px, 2.4vw, 32px);            /* a serif line that introduces a section */
  --t-lede: clamp(19px, 1.8vw, 26px);           /* the serif line under a page title */
  --t-title: clamp(44px, 5.3vw, 76px);            /* a page's title (56 to 80px on a wide screen) */
  --t-title-s: clamp(40px, 10.6vw, 50px);       /* a bag's title, the 404 line */
  --t-mail: clamp(32px, 4.6vw, 64px);
  /* space: --gap between sections, --gap-in between sections of one chapter, --band-pad inside a colour band */
  --gap: clamp(88px, 22vw, 112px);
  --gap-in: clamp(64px, 8vw, 120px);
  --band-pad: clamp(88px, 10vw, 152px);
  --serif: Gambetta, "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --sans: Author, "Segoe UI", Helvetica, Arial, sans-serif;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-leave: cubic-bezier(0.4, 0, 1, 1);
}
@media (min-width: 560px) { :root { --pad: clamp(24px, 4vw, 48px); } }
@media (min-width: 760px) { :root { --t-h2: clamp(34px, 3.5vw, 50px); --t-say: clamp(34px, 3.5vw, 50px); --t-title-s: clamp(42px, 4.6vw, 72px); --gap: clamp(112px, 11.5vw, 176px); } }
@media (min-width: 900px) { :root { --mast: 72px; --t-body: 16px; } }
@media (min-width: 1440px) { :root { --max: 1280px; } }
@media (min-width: 1800px) { :root { --max: 1360px; } }

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--mast) + 24px); }
body { background: var(--page); color: var(--ink); font-family: var(--sans); font-size: var(--t-body); line-height: 1.6; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; overflow-x: hidden; overflow-x: clip; }
body.is-locked { overflow: hidden; }
img, svg { display: block; }
img { max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
ul, ol, dl, dd { list-style: none; padding: 0; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
figure { margin: 0; }
[hidden] { display: none !important; }
::selection { background: #ffdeb2; color: var(--ink); }
:focus-visible { outline: 1.5px solid var(--ink); outline-offset: 3px; }
.skip { position: absolute; left: 12px; top: -60px; z-index: 50; background: var(--ink); color: var(--page); padding: 10px 16px; font-size: var(--t-small); transition: top 200ms; }
.skip:focus { top: 12px; }

/* ------------------------------------------------------------------ type */
h1, h2, h3 { font-family: var(--serif); font-weight: 400; text-wrap: balance; }
h2 { font-size: var(--t-h2); line-height: 1.06; letter-spacing: -0.016em; }
p, figcaption, dd, blockquote { text-wrap: balance; }
.label { font-family: var(--sans); font-size: var(--t-label); line-height: 1.5; letter-spacing: 0.14em; text-transform: uppercase; color: var(--quiet); font-weight: 500; }
.link { font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; padding-bottom: 4px; background: linear-gradient(var(--ink), var(--ink)) 0 100% / 100% 1px no-repeat; transition: background-size 420ms var(--ease); }
.link:hover { background-size: 0 1px; background-position: 100% 100%; }
.link { position: relative; }
.link::after { content: ""; position: absolute; inset: -12px -10px -10px; }
.wrap { max-width: var(--max); margin-inline: auto; padding-inline: var(--pad); }
.sec { padding-top: var(--gap); }

/* --------------------------------------------------------------- buttons */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 16px; height: 50px; padding: 0 26px; background: var(--ink); color: var(--page); font-size: var(--t-label); letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; white-space: nowrap; transition: background-color 320ms var(--ease), color 320ms var(--ease), transform 140ms; }
.btn:hover { background: #24305c; }
.btn:active { transform: translateY(1px); }
.btn .price { letter-spacing: 0.06em; padding-left: 16px; border-left: 1px solid currentColor; line-height: 1.4; font-variant-numeric: tabular-nums; }
.btn--light { background: var(--page); color: var(--ink); }
.btn--light:hover { background: #fff; }

/* ---------------------------------------------------------------- ticker */
.ticker { overflow: hidden; height: var(--tick); display: flex; align-items: center; background: var(--ink); color: rgba(247, 245, 241, 0.86); font-size: var(--t-label); letter-spacing: 0.15em; text-transform: uppercase; font-weight: 500; }
/* Homepage only (the only page with [data-cover]): over the navy slide the bar is peach, so it does not melt into the
   wall; over a light slide it is navy as on every other page. The cover's data-tone starts "dark" in the markup and the
   inline script in index.html sets it before the first paint, so there is no flash and no dependence on later scripts. */
.ticker, .ticker span::after { transition: background-color 800ms var(--ease), color 800ms var(--ease); }
body:has([data-cover][data-tone="dark"]) .ticker { background: var(--peach); color: var(--ink); }
body:has([data-cover][data-tone="dark"]) .ticker span::after { background: rgba(17, 26, 59, 0.45); }
@media (prefers-reduced-motion: reduce) { .ticker, .ticker span::after { transition: none; } }
.ticker .track { display: flex; width: max-content; animation: ticker 80s linear infinite; }
.ticker:hover .track { animation-play-state: paused; }
.ticker span { display: inline-flex; align-items: center; white-space: nowrap; min-width: 34vw; }
.ticker span::after { content: ""; width: 3px; height: 3px; border-radius: 50%; background: rgba(247, 245, 241, 0.5); margin: 0 56px; }
@keyframes ticker { to { transform: translateX(-50%); } }

/* -------------------------------------------------------------- masthead */
/* Sits over the opening photograph in white; turns to paper once the photograph has passed.
   Leaves when the page moves down, returns the moment it moves up. */
.mast { position: sticky; top: 0; z-index: 30; height: var(--mast); margin-bottom: calc(var(--mast) * -1); color: #fff; border-bottom: 1px solid transparent; transition: transform 460ms var(--ease), background-color 320ms, color 320ms, border-color 320ms; }
.mast.is-solid { background: rgba(247, 245, 241, 0.92); -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3); color: var(--ink); border-bottom-color: var(--line); }
.mast.is-hidden { transform: translateY(-104%); transition: transform 320ms var(--ease-leave), background-color 320ms, color 320ms, border-color 320ms; }
.mast .in { height: 100%; padding: 0 var(--pad); display: grid; grid-template-columns: 1fr max-content 1fr; align-items: center; }
.mast nav, .mast .side { display: flex; align-items: center; gap: 28px; font-size: var(--t-label); letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; }
.mast .side { justify-content: flex-end; }
.mast nav a, .mast nav button, .mast .side a, .mast .side button { min-height: 44px; display: inline-flex; align-items: center; position: relative; white-space: nowrap; letter-spacing: inherit; text-transform: inherit; font-weight: inherit; }
.mast nav a::after, .mast .side a::after, .mast .side button::after, .mast nav button::after { content: ""; position: absolute; left: 0; right: 0; bottom: 10px; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: right; transition: transform 240ms var(--ease-leave); }
.mast nav a:hover::after, .mast .side a:hover::after, .mast .side button:hover::after, .mast nav button:hover::after { transform: scaleX(1); transform-origin: left; transition: transform 360ms var(--ease); }
.mast .brand { justify-self: center; display: block; padding: 6px 0; }
.mast .brand img { height: 32px; width: auto; filter: brightness(0) invert(1); transition: filter 320ms; }
.mast.is-solid .brand img { filter: none; }
/* over a light photograph in the opening the header is ink (js/app.js sets .on-light with the slide) */
.mast.on-light:not(.is-solid) { color: var(--ink); }
.mast.on-light:not(.is-solid) .brand img { filter: none; }
.mast a.desk { display: none; }
.mast :focus-visible { outline-color: currentColor; }

/* ---------------------------------------------------------------- covers */
/* The photographs that open and close the page. Words are set into the quiet side of each. */
.cover { position: relative; isolation: isolate; overflow: hidden; color: #fff; background: #1b2844; height: calc(100vh - var(--tick)); height: calc(100svh - var(--tick)); min-height: 560px; max-height: 1080px; }
.cover-media { position: absolute; inset: 0; z-index: -2; transform-origin: 60% 62%; animation: settle 2400ms var(--ease) both; }
/* The opening's three photographs (25 Oct), stacked, one on show (.is-on). Each slide is a wall of its own: where its
   photograph is set smaller than the opening (a phone), the slide's ground carries the wall on (--g1 above the
   photograph's top at --gt, --g2 below its foot at --gb) and the photograph's edges inside the opening fade into it
   (--ft --fr --fb --fl, .is-faded). The script after the opening in index.html places each photograph around its bag
   (--x --y --w --h); without it the photograph simply fills the opening. A new slide fades in over the one leaving
   (.was-on stays under it until it is in) and settles as it comes, as the opening does, from its bag (--sx --sy).
   The whole stack drifts with the page on a mouse (js/app.js). */
.cover-slides { position: absolute; inset: 0; will-change: transform; }
/* (C2) beside the words the photograph may stop short of the left edge (behind the words) or, on a very wide screen,
   of the right one (the navy and the white: data-open): there the ground is the wall's colour at that edge of the
   photograph (--gl1/--gl2, --gr1/--gr2, top to foot), under the photograph's fade (--gxl, --gxr: the gap) */
.slide { --pos: 50% 50%; position: absolute; inset: 0; overflow: hidden; opacity: 0; visibility: hidden; transform-origin: var(--sx, 66%) var(--sy, 50%);
  background: linear-gradient(180deg, var(--gl1, transparent), var(--gl2, transparent)) 0 0 / calc(var(--gxl, 0px) + var(--fl, 0px)) 100% no-repeat,
    linear-gradient(180deg, var(--gr1, transparent), var(--gr2, transparent)) 100% 0 / calc(var(--gxr, 0px) + var(--fr, 0px)) 100% no-repeat,
    linear-gradient(180deg, var(--g1) var(--gt, 0%), var(--g2) var(--gb, 100%)); }
.slide.is-on { z-index: 2; opacity: 1; visibility: visible; transition: opacity 800ms var(--ease), visibility 0s; }
.slide.was-on { z-index: 1; opacity: 1; visibility: visible; }
.slide img { position: absolute; left: var(--x, 0px); top: var(--y, 0px); width: var(--w, 100%); height: var(--h, 100%); max-width: none; object-fit: cover; object-position: var(--pos); }
.slide.is-faded img { -webkit-mask-image: linear-gradient(180deg, transparent var(--fa, 0px), #000 var(--ft), #000 calc(100% - var(--fb)), transparent), linear-gradient(90deg, transparent, #000 var(--fl), #000 calc(100% - var(--fr)), transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(180deg, transparent var(--fa, 0px), #000 var(--ft), #000 calc(100% - var(--fb)), transparent), linear-gradient(90deg, transparent, #000 var(--fl), #000 calc(100% - var(--fr)), transparent); mask-composite: intersect; }
/* on the navy wall a soft shade at the top keeps the white header clear of the leaf light; on the ivory, a soft light
   one keeps the ink header clear of the banyan's leaves where they reach the top */
.slide::after { content: ""; position: absolute; inset: 0; pointer-events: none; }
.slide[data-tone="dark"]::after { background: linear-gradient(180deg, rgba(6, 10, 28, 0.42) 0%, rgba(6, 10, 28, 0) 24%); }
.slide--ivory::after { background: linear-gradient(180deg, rgba(242, 237, 230, 0.78) 0, rgba(242, 237, 230, 0.6) 56px, rgba(242, 237, 230, 0) 150px); }
@keyframes slide-settle { from { transform: scale(1.035); } to { transform: none; } }
@media (prefers-reduced-motion: no-preference) { .slide.is-new { animation: slide-settle 1600ms var(--ease) both; } }
/* the first frame is drawn as it stands: the slide the address names, in its own tone, with nothing moving into place */
.cover.is-still, .cover.is-still *, .mast.is-still, .mast.is-still * { transition: none !important; }
@media (max-width: 899px) {
  /* (without the script, the photograph fills the opening, its bag near the middle) */
  .slide { --pos: 78% 50%; }
  /* the bag sits between the headline and the button: a wide, short window grows the opening with its width, so
     the bag keeps a fair size (the words and the button take about 410px) */
  .cover[data-cover] { min-height: max(560px, calc(47vw + 410px)); }
}
.cover-copy { position: absolute; z-index: 1; left: var(--pad); right: var(--pad); top: calc(var(--mast) + 26px); bottom: calc(24px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; }
.cover-kicker { font-family: var(--serif); font-style: italic; font-size: var(--t-lead); line-height: 1.3; color: rgba(255, 255, 255, 0.9); }
.cover { --h1: clamp(40px, 11.6vw, 54px); }
.cover h1, .cover h2 { color: #fff; font-size: var(--h1); line-height: 1.02; letter-spacing: -0.022em; }
.cover h1 { margin-top: 10px; }
.cover h1 .ln { display: block; overflow: hidden; padding-bottom: 0.16em; margin-bottom: -0.16em; }
.cover h1 .ln > span { display: block; animation: line-up 1100ms var(--ease) both; }
.cover h1 .ln:nth-child(1) > span { animation-delay: 260ms; }
.cover h1 .ln:nth-child(2) > span { animation-delay: 360ms; }
.cover-sub { margin-top: 14px; max-width: 21em; font-size: var(--t-body); line-height: 1.55; color: rgba(255, 255, 255, 0.88); }
[data-cover] .cover-sub { display: none; }
.cover-act { margin-top: auto; display: grid; gap: 18px; }
.cover-act .btn { width: 100%; }
.cover-six { display: flex; align-items: center; justify-content: center; gap: 14px; font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: rgba(255, 255, 255, 0.86); }
/* under 560 the words beside the dots keep the width "Six leathers" has at rest (a longer leather's name runs on to the right), so naming a leather never moves the dots */
@media (max-width: 559.98px) { .cover-six > span { display: block; width: 7.3em; white-space: nowrap; } }
.dots { display: flex; gap: 2px; }
.dots a { display: grid; place-items: center; width: 24px; height: 44px; }
.dots a::before { content: ""; width: 12px; height: 12px; border-radius: 50%; background: var(--c); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.62); transition: transform 320ms var(--ease), box-shadow 800ms var(--ease); }
.dots a:hover::before, .dots a:focus-visible::before { transform: scale(1.35); }
.cover :focus-visible { outline-color: #fff; }
.cover-kicker, .cover-sub, .cover-act, .cover-pager { animation: rise 900ms var(--ease) both; }
.cover-kicker { animation-delay: 180ms; }
.cover-sub { animation-delay: 520ms; }
.cover-act { animation-delay: 640ms; }
.cover-pager { animation-delay: 760ms; }

/* The control: which photograph is on show (1 / 3) between a step back and a step on, in the label's type. Bottom
   right, its last chevron on the column's edge: just above the button on a phone, beside it from 560, in the corner
   from 900. Hidden without the script. */
.cover-pager { position: absolute; z-index: 1; right: calc(var(--pad) - 18.5px); bottom: calc(142px + env(safe-area-inset-bottom, 0px)); display: flex; align-items: center; font-size: var(--t-label); line-height: 1; letter-spacing: 0.14em; font-weight: 500; font-variant-numeric: tabular-nums; color: rgba(255, 255, 255, 0.86); }
.cover-pager button { display: grid; place-items: center; width: 44px; height: 44px; }
.cover-pager svg { width: 7px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; transition: transform 240ms var(--ease); }
.cover-pager .count { padding-left: 0.14em; white-space: nowrap; }
.cover-pager [data-banner-now] { display: inline-block; }
.cover-pager :focus-visible { outline-offset: -6px; }
@media (hover: hover) {
  .cover-pager [data-banner-step="-1"]:hover svg { transform: translateX(-2px); }
  .cover-pager [data-banner-step="1"]:hover svg { transform: translateX(2px); }
}
@media (min-width: 560px) { .cover-pager { bottom: calc(89px + env(safe-area-inset-bottom, 0px)); } }

/* a light wall (the white, the ivory): the words, the dots' rings, the control and the button turn ink, in step with
   the photograph coming in; the header over the opening turns ink with them (.mast.on-light) */
.cover-kicker, .cover h1, .cover-sub, .cover-six, .cover-pager { transition: color 800ms var(--ease); }
.cover[data-tone="light"] .cover-kicker { color: rgba(17, 26, 59, 0.86); }
.cover[data-tone="light"] h1 { color: var(--ink); }
.cover[data-tone="light"] .cover-sub { color: rgba(17, 26, 59, 0.8); }
.cover[data-tone="light"] .cover-six { color: rgba(17, 26, 59, 0.8); }
.cover[data-tone="light"] .cover-pager { color: var(--ink); }
.cover[data-tone="light"] .dots a::before { box-shadow: 0 0 0 1px rgba(17, 26, 59, 0.4); }
.cover[data-tone="light"] .btn--light { background: var(--ink); color: var(--page); }
.cover[data-tone="light"] .btn--light:hover { background: #24305c; }
.cover[data-tone="light"] :focus-visible { outline-color: var(--ink); }
@keyframes settle { from { transform: scale(1.07); } to { transform: none; } }
@keyframes line-up { from { transform: translateY(108%); } to { transform: none; } }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }


/* ---------------------------------------------------------------- closing */
/* The last photograph: a woman on a sunlit stone street, the bag across her body. On a phone the picture
   comes first, edge to edge, with the words beneath it on the page. From 900 the photograph is a banner at
   its own proportions, and the words sit in ink on the quiet stone wall to her left. */
.closing { margin-top: var(--gap); display: flex; flex-direction: column; }
.makers-band + .closing { margin-top: 0; }
.closing-media { position: relative; aspect-ratio: 1; overflow: hidden; background: #dcc9ab; }
.closing-media img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; object-position: 66% 50%; }
.closing-copy { position: relative; z-index: 1; padding: 36px var(--pad) 0; }
.closing h2 { font-size: var(--t-h2); line-height: 1.06; letter-spacing: -0.02em; max-width: 9.5em; }
.closing .sub { margin-top: 14px; color: var(--soft); max-width: 24em; }
.closing .act { margin-top: 26px; display: grid; gap: 16px; }
.closing .act .btn { width: 100%; }
.closing .fine { font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--soft); text-align: center; }

/* --------------------------------------------------------------- the six */
/* the hairline under the head is its ::after, so it can draw in (data-reveal="draw"); the border keeps its 1px */
.shop-head { position: relative; display: grid; gap: 18px; padding-bottom: 28px; border-bottom: 1px solid transparent; }
.shop-head::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--line); }
.shop-head .aside { max-width: 31em; color: var(--ink); }
.shop-head .terms { margin-top: 10px; }
.bags { display: grid; grid-template-columns: 1fr; gap: 52px 28px; margin-top: 36px; }
.bag { position: relative; scroll-margin-top: calc(var(--mast) + 24px); }
.bag .tag { display: block; min-height: 16px; margin-bottom: 4px; font-size: var(--t-label); line-height: 16px; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--plum); }
/* the leather first, the bag on top of it: the render sits on its own page-coloured layer so its white
   ground still melts away under the multiply blend */
.bag-shot { position: relative; width: 100%; aspect-ratio: 4 / 3; overflow: hidden; background: var(--line-soft); }
.bag-shot .swatch { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 1400ms cubic-bezier(0.33, 0, 0.2, 1); }
.bag-view { position: absolute; inset: 0; isolation: isolate; background: var(--page); opacity: 0; transition: opacity 650ms cubic-bezier(0.45, 0, 0.25, 1); }
.bag-view .render { position: absolute; left: 0; top: 50%; width: 100%; height: auto; max-width: none; transform: translateY(-50%) scale(0.985); mix-blend-mode: multiply; transition: transform 1000ms cubic-bezier(0.33, 0, 0.2, 1); }
.bag-shot.is-turned .bag-view, .bag:focus-within .bag-view { opacity: 1; }
.bag-shot.is-turned .bag-view .render, .bag:focus-within .bag-view .render { transform: translateY(-50%); }
.bag-shot.is-turned .swatch { transform: scale(1.04); }
.flip-hint { position: absolute; left: 10px; bottom: 10px; z-index: 2; padding: 6px 10px; background: rgba(247, 245, 241, 0.92); font-size: var(--t-label); line-height: 1; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--ink); pointer-events: none; }
.flip-hint .to-leather, .is-turned .flip-hint .to-bag { display: none; }
.is-turned .flip-hint .to-leather { display: inline; }
@media (hover: hover) and (pointer: fine) { .flip-hint { display: none; } }
.bag-meta { position: relative; padding-top: 16px; border-top: 1px solid var(--line); }
/* the thread: a stitch of the leather's own colour, drawn the full width when the bag is under the hand */
.bag-meta::before { content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 2px; background: var(--c); transform: scaleX(0.085); transform-origin: left; transition: transform 800ms var(--ease); }
.bag:hover .bag-meta::before, .bag:focus-within .bag-meta::before, .bag.is-called .bag-meta::before { transform: scaleX(1); }
.bag-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.bag-name { font-size: var(--t-name); line-height: 1.2; letter-spacing: -0.008em; }
.bag-price { font-size: var(--t-body); font-variant-numeric: tabular-nums; }
.bag-fin { margin-top: 3px; }
.bag-line { margin-top: 10px; font-size: var(--t-body); color: var(--soft); max-width: 27em; }
.bag-buy { margin-top: 16px; display: inline-flex; align-items: center; height: 42px; padding: 0 20px; box-shadow: 0 0 0 1px var(--ink) inset; font-size: var(--t-label); letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; transition: background-color 320ms var(--ease), color 320ms var(--ease); }
.bag-buy:hover, .bag-buy.is-added { background: var(--ink); color: var(--page); }
/* the picture and the name lead to the bag's own page */
@media (hover: hover) and (pointer: fine) { .bags .bag-shot { cursor: pointer; } }
.shop-note { margin-top: 44px; font-family: var(--serif); font-style: italic; font-size: var(--t-small); line-height: 1.55; color: var(--soft); max-width: 46em; }

/* ---------------------------------------------------------- photographs */
/* every photograph lives in a .ph box of a fixed shape, so a replaced file can never move the layout */
.ph { overflow: hidden; }
.ph img { width: 100%; height: 100%; object-fit: cover; }
/* [data-ph] photographs develop as they arrive: css/motion.css */
figcaption { font-size: var(--t-small); line-height: 1.5; color: var(--soft); }

/* ---------------------------------------------------------------- makers */
.makers-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; grid-template-areas: "head head" "a a" "body body" "b c"; }
.m-head { grid-area: head; margin-bottom: 14px; }
.m-a { grid-area: a; } .m-b { grid-area: b; } .m-c { grid-area: c; }
.m-a .ph { aspect-ratio: 3 / 2; }
.m-b .ph, .m-c .ph { aspect-ratio: 4 / 5; }
.makers figcaption { margin-top: 10px; }
.m-body { grid-area: body; padding: 18px 0 30px; }
.m-body p { color: var(--soft); max-width: 36em; }
.m-body p:not(.share) + p:not(.share) { margin-top: 14px; }
.m-body .share { margin-top: 20px; font-family: var(--serif); font-size: var(--t-h3); line-height: 1.36; letter-spacing: -0.006em; color: var(--ink); max-width: 21em; text-wrap: balance; }
.m-body .link { display: inline-block; margin-top: 24px; }

/* -------------------------------------------------------------- promises */
.promises { margin-top: var(--gap-in); display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.promises li { display: flex; padding: 28px 10px 24px; }
.promises li:nth-child(even) { border-left: 1px solid var(--line-soft); }
.promises li:nth-child(n + 3) { border-top: 1px solid var(--line-soft); }

/* --------------------------------------------------------------- the bag */
.anatomy { display: grid; gap: 28px; }
.open { display: grid; gap: 10px; justify-items: center; text-align: center; }
.open .shot { position: relative; width: 100%; aspect-ratio: 16 / 10; overflow: hidden; }
/* the top view lays the strap out above the bag and the tassels below it, so the picture is set a little smaller
   and centred on the bag itself, keeping strap and tassels whole inside the wide frame */
.open .shot img { position: absolute; left: 3%; top: 50%; width: 94%; height: auto; max-width: none; transform: translateY(-51.5%); mix-blend-mode: multiply; }
.open-line { font-family: var(--serif); font-style: italic; font-size: var(--t-lead); line-height: 1.3; color: var(--soft); }
.open figcaption { font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--quiet); }
.anatomy .lead { margin-top: 16px; font-family: var(--serif); font-size: var(--t-lead); line-height: 1.45; color: var(--soft); max-width: 25em; }
.pockets { margin-top: 28px; border-top: 1px solid var(--line); }
.pockets > div { display: grid; gap: 3px 20px; padding: 15px 0; border-bottom: 1px solid var(--line); }
.pockets dt { font-family: var(--serif); font-size: var(--t-lead); line-height: 1.3; text-wrap: balance; }
.pockets dd { color: var(--soft); font-size: var(--t-body); line-height: 1.55; }
.specs { margin-top: 24px; display: grid; grid-template-columns: 1fr 1fr; gap: 16px 20px; }
.specs dt { font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--quiet); }
.specs dd { margin-top: 2px; font-size: var(--t-body); }

/* ------------------------------------------------------------ the groups */
/* Allie's order (21 Oct) puts related sections side by side: the icon row, the bag's features and the four ways
   form one group, as do Partners & friends and the process. Inside a group the gap is smaller than between groups. */
.promises-wrap + .anatomy, .anatomy + .ways { padding-top: var(--gap-in); }

/* ------------------------------------------------------------- four ways */
/* Words on the left, one photograph on the right: the strap end, ring and buckle that make the four ways
   possible, lying on a raw hide. Field notes sits in the same column, under the four ways. */
.ways { display: grid; gap: 28px; }
.ways-words { display: contents; }
.ways h2 { order: 0; }
.ways-photo { order: 1; }
.ways-photo .ph { aspect-ratio: 4 / 5; }
.ways-grid { order: 2; display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--line); }
.ways-grid li { padding: 16px 14px 18px 0; border-bottom: 1px solid var(--line); font-family: var(--serif); font-size: var(--t-lead); line-height: 1.35; color: var(--ink); text-wrap: balance; }
.ways-grid li:nth-child(even) { padding: 16px 0 18px 14px; border-left: 1px solid var(--line); }
.field-notes { order: 3; margin-top: 8px; }
.field-notes h3 { font-size: var(--t-h3); font-style: italic; letter-spacing: -0.006em; }
.field-notes p { margin-top: 8px; color: var(--soft); max-width: 34em; }

/* ----------------------------------------------------------- in the wild */
/* Its own section: one line under the heading, the four customers below, each named by the way she wears it. */
.wild-head { text-align: center; margin-bottom: 36px; }
.wild-head p { margin: 12px auto 0; color: var(--soft); max-width: 30em; }
.wild-head a { color: var(--ink); background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; padding-bottom: 2px; transition: background-size 420ms var(--ease); }
.wild-head a:hover { background-size: 0 1px; background-position: 100% 100%; }
.wear { display: grid; grid-template-columns: 1fr 1fr; gap: 28px 14px; }
.wear .ph { aspect-ratio: 4 / 5; }
.wear figcaption { margin-top: 10px; font-family: var(--serif); font-size: var(--t-lead); line-height: 1.3; color: var(--ink); }

/* --------------------------------------------------------------- process */
/* The five steps, all in view at once and still, inside the makers' band after the viewer. A phone: a list, each
   photograph (40% of the column, 3:4) beside its words, the stitched thread running down the photo column between
   them. From 900: one even row of five, the thread beneath the photographs and above their captions, from the first to
   the last. The thread is drawn once, as the row arrives (css/motion.css). */
.making { margin-top: var(--gap-in); }
.making-head { margin-bottom: clamp(36px, 6vw, 52px); }
.making-head h2 { margin-top: 10px; }
.making-head p:not(.label) { margin-top: 16px; color: var(--soft); max-width: 37em; }
.steps-wrap { position: relative; --sg: clamp(14px, 1.6vw, 24px); --cut: 0 0 100% 0; }
.steps { position: relative; z-index: 1; display: grid; gap: 40px; }
.steps figure { display: grid; grid-template-columns: 40% minmax(0, 1fr); column-gap: clamp(18px, 5vw, 32px); align-items: center; }
.steps .ph { aspect-ratio: 3 / 4; background: var(--powder); }
.steps figcaption { max-width: 16em; }
.steps figcaption b { display: block; font-family: var(--serif); font-size: var(--t-lead); line-height: 1.3; font-weight: 400; color: var(--ink); }
/* the thread: the link stitch (4px on, 3px off) in navy at 40%, 1.5px fine */
.steps-wrap > .thread { clip-path: inset(0); position: absolute; z-index: 0; left: calc(20% - 0.75px); top: 0; bottom: 0; width: 1.5px; color: color-mix(in srgb, var(--ink) 40%, transparent); background: repeating-linear-gradient(180deg, currentColor 0 4px, transparent 4px 7px); pointer-events: none; }

/* ------------------------------------------------------------- manifesto */
/* a navy band: the label in dusty, the two sentences cream (the second one softer), the link cream with the stitch */
.manifesto { text-align: center; }
.manifesto .label { color: var(--dusty); }
.manifesto .say { margin: 18px auto 0; max-width: 19em; font-family: var(--serif); font-size: var(--t-say); line-height: 1.2; letter-spacing: -0.016em; text-wrap: balance; }
.manifesto .say--soft { margin-top: 0.55em; color: var(--on-navy-soft); }
.manifesto .link { display: inline-block; margin-top: 34px; color: var(--on-navy); }
.band--navy :focus-visible { outline-color: var(--on-navy); }

/* ---------------------------------------------------- partners & friends */
/* The makers' chapter, on powder (.makers-band; the process follows it in the same band). A portrait viewer: from 900, with
   JavaScript, her words and the ten names on the left, one large 4:5 portrait on the right, brought forward by a
   name with a slow cross-fade (620ms in, 260ms out; instant under reduced motion). It never changes on its own.
   Under 900, and without JavaScript, the names give way to a strip of the ten portraits to swipe, each about 78% of
   the screen wide with the next one peeking, name and craft under each. */
.viewer-words p { margin-top: 16px; color: var(--soft); max-width: 34em; }
.roll-call { display: none; }
.viewer-stage { display: flex; gap: 12px; margin: 32px calc(var(--pad) * -1) 0; padding: 0 var(--pad) 12px; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-padding-inline: var(--pad); scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
/* about 78% of the screen wide, and never taller than the screen can show with its caption (a phone on its side) */
.frame { flex: 0 0 min(78vw, (100vh - 90px) * 0.8); flex-basis: min(78vw, (100svh - 90px) * 0.8); scroll-snap-align: start; }
.frame .ph { aspect-ratio: 4 / 5; background: var(--line-soft); }
.frame figcaption { margin-top: 12px; }
.frame .nm { display: block; font-family: var(--serif); font-size: var(--t-lead); line-height: 1.25; color: var(--ink); }
.frame .craft { display: block; margin-top: 2px; font-size: var(--t-small); line-height: 1.4; color: var(--soft); }
/* without JavaScript a wide screen keeps the strip, at a size that suits it */
@media (min-width: 900px) { html:not(.js) .frame { flex-basis: clamp(260px, 27vw, 380px); } }

@media (min-width: 900px) {
  /* the portrait's caption hangs beneath it, outside the grid row: the viewer keeps room for it at its foot, so
     whatever follows in the band (the process) starts below the caption */
  html.js .viewer { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: clamp(48px, 6.5vw, 112px); padding-bottom: calc(16px + var(--t-h3) * 1.25); }
  html.js .viewer-words { display: flex; flex-direction: column; }
  html.js .viewer-words p { margin-top: 20px; max-width: 32em; }

  /* the roll call: two columns of six, read down; it fills the column to the portrait's bottom edge */
  html.js .roll-call { flex: 1 0 auto; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: repeat(6, 1fr); grid-auto-flow: column; column-gap: clamp(24px, 3vw, 44px); margin-top: 40px; }
  /* at 1024 the portrait is shorter than twelve full rows: tighter rows and a shorter lead-in keep the list near its foot */
  @media (max-width: 1199px) { html.js .roll-call { margin-top: 28px; } html.js .roll-call .who { padding: 4px 0; } }
  .roll-call li { display: flex; border-top: 1px solid var(--line); }
  .roll-call li:nth-child(6n) { border-bottom: 1px solid var(--line); }
  .roll-call .who { display: grid; grid-template-columns: 48px minmax(0, 1fr); align-content: center; column-gap: 16px; width: 100%; padding: 7px 0; text-align: left; }
  .roll-call .who img { grid-row: 1 / 3; grid-column: 1; width: 48px; height: 48px; object-fit: cover; transition: box-shadow 240ms var(--ease); }
  .roll-call .who .nm { grid-row: 1; grid-column: 2; align-self: end; font-family: var(--serif); font-size: var(--t-lead); line-height: 1.2; color: var(--soft); transition: color 240ms var(--ease); }
  .roll-call .who .craft { grid-row: 2; grid-column: 2; align-self: start; margin-top: 4px; font-size: var(--t-label); line-height: 1.3; letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--soft); }
  /* the one on show: its name in full ink, a fine ink ring around its face */
  .roll-call .who[aria-pressed="true"] .nm, .roll-call .who:focus-visible .nm { color: var(--ink); }
  .roll-call .who[aria-pressed="true"] img { box-shadow: 0 0 0 2px var(--powder), 0 0 0 3px var(--ink); }

  /* the stage: the ten portraits stacked in one cell, one on show; its caption hangs beneath the photograph */
  html.js .viewer-stage { display: grid; align-self: start; margin: 0; padding: 0; overflow: visible; scroll-snap-type: none; }
  /* only the one leaving fades (.was-on, set by js/motion.js), under the one coming in; the rest are simply hidden */
  html.js .frame { grid-area: 1 / 1; position: relative; opacity: 0; visibility: hidden; }
  /* a portrait neither on show nor leaving takes no part in the page, so its lazy picture is not fetched: js/motion.js
     loads it when its name is pointed at, focused or pressed, and brings it forward once it is ready */
  html.js .frame:not(.is-on):not(.was-on) { display: none; }
  html.js .frame.is-on { z-index: 1; opacity: 1; visibility: visible; transition: opacity 620ms var(--ease), visibility 0s; }
  html.js .frame.was-on { transition: opacity 260ms var(--ease-leave) 240ms, visibility 0s linear 500ms; }
  /* coming back from display: none, the one coming in starts from nothing (once the viewer has been used, so the
     first portrait is simply there when the page opens) */
  @starting-style { html.js .viewer.is-live .frame.is-on, html.js .viewer.is-live .frame.is-on figcaption { opacity: 0; } }
  html.js .frame figcaption { position: absolute; top: 100%; left: 0; right: 0; margin-top: 16px; display: flex; align-items: baseline; gap: 14px; }
  /* the captions sit on bare ground, so they never cross: the old name goes at once, the new one follows */
  html.js .frame:not(.is-on) figcaption { opacity: 0; transition: opacity 180ms var(--ease-leave); }
  html.js .frame.is-on figcaption { transition: opacity 520ms var(--ease) 180ms; }
  html.js .frame .nm { font-size: var(--t-h3); }
  html.js .frame .craft { margin: 0; font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; }
}
@media (hover: hover) and (min-width: 900px) { .roll-call .who:hover .nm { color: var(--ink); } }
@media (prefers-reduced-motion: reduce) {
  html.js .frame, html.js .frame figcaption, .roll-call .who .nm, .roll-call .who img { transition: none !important; }
}

/* ---------------------------------------------------------------- quotes */
/* Three notes as Allie received them: a text, an Instagram message, an email. Drawn in the page rather than
   pasted in as pictures, so the words stay real text. Each is a cropped phone screen of one size, with just
   enough of its app to be recognised; no logos, no invented times, usernames or replies. */
.quotes h2 { margin-bottom: 36px; text-align: center; }
.notes { --ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", "Segoe UI", Helvetica, Arial, sans-serif; display: grid; gap: 44px; justify-items: center; }
.notes > li { width: min(100%, 360px); display: flex; }
.note { flex: 1; display: flex; flex-direction: column; }
.screen { flex: 1; display: flex; flex-direction: column; background: #fff; border-radius: 28px; overflow: hidden; font-family: var(--ui); color: #000; letter-spacing: 0; -webkit-font-smoothing: antialiased; box-shadow: 0 0 0 1px rgba(17, 26, 59, 0.07), 0 26px 56px -30px rgba(17, 26, 59, 0.38); }
.screen .i { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.screen p { max-width: none; }
.screen blockquote { margin: 0; }
.screen blockquote p { text-wrap: pretty; }
.screen .av { width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; flex: none; color: #fff; font-size: 16px; font-weight: 500; line-height: 1; background: linear-gradient(180deg, #a9aeb8, #868b96); }
.screen .thread { flex: 1; min-height: 150px; display: flex; flex-direction: column; justify-content: center; }
.note figcaption { margin-top: 16px; display: flex; justify-content: center; align-items: baseline; gap: 10px; }
.note figcaption b { font-family: var(--serif); font-weight: 400; font-size: var(--t-lead); line-height: 1.3; color: var(--ink); }
.note figcaption span { font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--soft); }

/* a text message */
.sms .bar { position: relative; display: flex; justify-content: center; padding: 12px 14px 9px; background: #f6f6f8; border-bottom: 1px solid #e2e2e7; }
.sms .bar > .i { position: absolute; left: 10px; top: 20px; width: 26px; height: 26px; color: #0a84ff; stroke-width: 2.2; }
.sms .who { display: grid; justify-items: center; gap: 4px; }
.sms .nm { display: inline-flex; align-items: center; font-size: 11.5px; line-height: 1; }
.sms .nm .i { width: 11px; height: 11px; color: #8e8e93; stroke-width: 2.6; }
.sms .thread { padding: 14px 12px 10px; }
.sms .stamp { align-self: center; margin-bottom: 10px; font-size: 11px; line-height: 1.3; color: #8e8e93; }
.sms blockquote { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.sms blockquote p { max-width: 84%; padding: 8px 13px; border-radius: 19px; background: #e9e9eb; font-size: 15px; line-height: 1.34; }
.sms blockquote p:last-child { border-bottom-left-radius: 5px; }
.sms .compose { display: flex; align-items: center; gap: 8px; padding: 6px 10px 14px; }
.sms .plus { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: #e9e9eb; color: #808086; }
.sms .plus .i { width: 18px; height: 18px; stroke-width: 2.2; }
.sms .field { flex: 1; display: flex; align-items: center; justify-content: space-between; height: 34px; padding: 0 8px 0 13px; border: 1px solid #d5d5da; border-radius: 18px; font-size: 15px; color: #b3b3b8; }
.sms .field .i { width: 19px; height: 19px; color: #8e8e93; }

/* an Instagram message */
.dm .bar { display: flex; align-items: center; gap: 16px; padding: 13px 16px; border-bottom: 1px solid #efefef; }
.dm .who { flex: 1; display: flex; align-items: center; gap: 10px; font-size: 15px; font-weight: 600; }
.dm .av { background: linear-gradient(135deg, #d9c6ee, #f2b6c9 55%, #f8d2a6); }
.dm .bar .av { width: 30px; height: 30px; font-size: 13px; }
.dm .thread { padding: 14px 12px 12px; }
.dm .row { display: flex; align-items: flex-end; gap: 8px; }
.dm .row .av { width: 26px; height: 26px; font-size: 11px; }
.dm blockquote { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; min-width: 0; }
.dm blockquote p { max-width: 100%; padding: 10px 14px; border-radius: 22px; background: #efefef; font-size: 15px; line-height: 1.34; }
.dm .compose { display: flex; align-items: center; gap: 12px; height: 46px; margin: 2px 10px 14px; padding: 0 14px 0 6px; border-radius: 23px; background: #efefef; }
.dm .cam { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: #3797f0; color: #fff; }
.dm .cam .i { width: 19px; height: 19px; stroke-width: 1.9; }
.dm .field { flex: 1; font-size: 15px; color: #8e8e8e; }
.dm .compose > .i { width: 21px; height: 21px; }

/* an email */
.mail .bar { padding: 13px 12px 6px; color: #0a84ff; }
.mail .back { display: inline-flex; align-items: center; gap: 1px; font-size: 16px; }
.mail .back .i { width: 24px; height: 24px; stroke-width: 2.2; }
.mail .head { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 0 12px; padding: 8px 16px 14px; border-bottom: 1px solid #e5e5ea; }
.mail .sender { display: block; font-size: 15px; font-weight: 600; line-height: 1.3; }
.mail .to { display: block; font-size: 13px; line-height: 1.3; color: #8e8e93; }
.mail .subject { grid-column: 1 / -1; margin-top: 14px; font-size: 18px; font-weight: 600; line-height: 1.3; }
.mail .body { flex: 1; padding: 14px 16px 22px; }
.mail blockquote p { font-size: 15px; line-height: 1.5; }
.mail .tools { display: flex; justify-content: space-between; padding: 12px 24px 16px; border-top: 1px solid #e5e5ea; color: #0a84ff; }

/* ---------------------------------------------------------------- footer */
.footer { background: var(--navy); color: var(--on-navy); }
.footer :focus-visible { outline-color: var(--on-navy); }
.footer .wrap { padding-top: var(--gap-in); padding-bottom: calc(28px + env(safe-area-inset-bottom, 0px)); }
.footer .top { display: grid; gap: 40px; padding-bottom: 48px; border-bottom: 1px solid var(--line-navy); }
.footer .signoff { font-family: var(--serif); font-size: var(--t-say); line-height: 1.2; letter-spacing: -0.014em; max-width: 15em; text-wrap: balance; }
.footer .loves { display: inline-flex; align-items: baseline; gap: 0.32em; white-space: nowrap; font-style: italic; }
.footer .loves img { height: 0.92em; width: auto; transform: translateY(0.16em); filter: brightness(0) invert(1); opacity: 0.96; }   /* the navy mark, drawn light on navy */
.footer form { position: relative; display: flex; margin-top: 10px; border-bottom: 1px solid color-mix(in srgb, currentColor 38%, transparent); }
.footer input { flex: 1; min-width: 0; height: 48px; padding: 0 2px; border: 0; border-radius: 0; background: none; font: inherit; font-size: var(--t-input); color: var(--on-navy); }
.footer input::placeholder { color: rgba(247, 245, 241, 0.55); }
.footer input:focus-visible { outline: none; }
.footer input { caret-color: var(--on-navy); }
/* Chrome's autofill paints a pale blue ground and its own text colour: keep it navy and cream, and hold the flash back */
.footer input:-webkit-autofill, .footer input:-webkit-autofill:hover, .footer input:-webkit-autofill:focus { -webkit-text-fill-color: var(--on-navy); caret-color: var(--on-navy); box-shadow: 0 0 0 100px var(--navy) inset; transition: background-color 600000s 0s, color 600000s 0s; }
.footer form button { color: var(--on-navy); min-height: 48px; padding: 0 2px 0 14px; font-size: var(--t-label); letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; }
.footer .label { color: var(--dusty); }
.footer .fine { margin-top: 12px; font-size: var(--t-small); line-height: 1.55; color: var(--on-navy-soft); max-width: 34em; }
.footer .fine.is-done { color: var(--on-navy); font-family: var(--serif); font-size: var(--t-lead); }
.footer .cols { display: grid; grid-template-columns: repeat(3, auto); justify-content: space-between; gap: 36px 16px; padding-top: 44px; }
.footer .about { grid-column: 1 / -1; }
.footer .motto { font-family: var(--serif); font-style: italic; font-size: var(--t-h3); line-height: 1.3; }
.footer .place { margin-top: 6px; font-size: var(--t-small); color: var(--on-navy-soft); }
.footer h3 { font-family: var(--sans); font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--dusty); margin-bottom: 12px; }
.footer .cols ul { display: grid; gap: 0; font-size: var(--t-small); margin-top: -6px; }
.footer .cols li { display: flex; }
.footer .cols a { color: var(--on-navy-soft); transition: color 240ms var(--ease), background-size 360ms var(--ease); padding: 6px 0; background: linear-gradient(currentColor, currentColor) 0 calc(100% - 5px) / 0 1px no-repeat; }
.footer .cols a:hover, .footer .cols a:focus-visible { color: var(--on-navy); background-size: 100% 1px; }
.footer .legal { margin-top: 48px; display: flex; justify-content: space-between; gap: 8px 24px; flex-wrap: wrap; font-size: var(--t-small); color: var(--on-navy-soft); }

/* --------------------------------------------------------------- drawers */
.drawer { position: fixed; inset: 0; z-index: 40; visibility: hidden; transition: visibility 0s 480ms; }
.drawer .scrim { position: absolute; inset: 0; background: rgba(17, 26, 59, 0.32); opacity: 0; transition: opacity 240ms var(--ease-leave); }
.drawer .panel { position: absolute; left: 0; right: 0; bottom: 0; max-height: 90vh; max-height: 90svh; overflow: auto; overscroll-behavior: contain; padding: 18px var(--pad) calc(24px + env(safe-area-inset-bottom, 0px)); background: var(--page); transform: translateY(100%); transition: transform 320ms var(--ease-leave); }
.drawer .panel > * { opacity: 0; transition: opacity 200ms var(--ease-leave); }
.drawer.is-open { visibility: visible; transition-delay: 0s; }
.drawer.is-open .scrim { opacity: 1; transition: opacity 320ms var(--ease); }
.drawer.is-open .panel { transform: none; transition: transform 520ms var(--ease); }
.drawer.is-open .panel > * { opacity: 1; transition: opacity 360ms var(--ease) 160ms; }
.drawer.is-open .panel > :nth-child(2) { transition-delay: 220ms; }
.drawer.is-open .panel > :nth-child(n + 3) { transition-delay: 280ms; }
.drawer .top { display: flex; justify-content: space-between; align-items: center; min-height: 48px; }
.drawer .top h2 { font-size: var(--t-h3); letter-spacing: -0.01em; }
.drawer .top h2:focus-visible { outline: none; }
.drawer .top img { height: 28px; width: auto; }
.drawer .close { font-size: var(--t-label); letter-spacing: 0.16em; text-transform: uppercase; font-weight: 500; min-height: 44px; padding: 0 2px; }
.menu-drawer .items { margin-top: 10px; display: grid; }
.menu-drawer .items a { font-family: var(--serif); font-size: var(--t-h3); line-height: 1.2; letter-spacing: -0.01em; padding: 11px 0; border-bottom: 1px solid var(--line-soft); }
.menu-drawer .quiet { margin-top: 22px; display: grid; gap: 4px; font-size: var(--t-small); color: var(--soft); }
.menu-drawer .quiet a { min-height: 36px; display: flex; align-items: center; }
.cart-drawer .lines { margin-top: 8px; }
.cart-drawer .line { display: grid; grid-template-columns: 92px 1fr; gap: 16px; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--line-soft); }
.cart-drawer .line .shot { display: block; position: relative; aspect-ratio: 4 / 3; overflow: hidden; }
.cart-drawer .line .shot img { position: absolute; left: 0; top: 50%; width: 100%; height: auto; transform: translateY(-50%); mix-blend-mode: multiply; }
.cart-drawer .line .head-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.cart-drawer .line .nm { display: block; font-family: var(--serif); font-size: var(--t-lead); line-height: 1.25; }
.cart-drawer .line .fin { font-size: var(--t-small); color: var(--quiet); }
.cart-drawer .qty { display: flex; align-items: center; margin-top: 4px; margin-left: -14px; }
.cart-drawer .qty button { width: 40px; height: 40px; font-size: var(--t-body); }
.cart-drawer .qty span { min-width: 18px; text-align: center; font-variant-numeric: tabular-nums; }
.cart-drawer .qty .remove { width: auto; margin-left: auto; padding: 0 2px; font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--quiet); }
.cart-drawer .empty { margin-top: 18px; display: grid; gap: 18px; justify-items: start; color: var(--soft); }
.cart-drawer .sum { margin-top: 20px; display: grid; gap: 8px; }
.cart-drawer .sum .row { display: flex; justify-content: space-between; font-family: var(--serif); font-size: var(--t-h3); }
.cart-drawer .sum .fine { font-size: var(--t-small); line-height: 1.55; color: var(--quiet); }
.cart-drawer .sum .btn { margin-top: 12px; width: 100%; }
.cart-drawer .keep { display: block; text-align: center; font-size: var(--t-label); letter-spacing: 0.14em; text-transform: uppercase; font-weight: 500; color: var(--soft); min-height: 44px; line-height: 44px; }
.live, .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ============================================================== 560 and up */
@media (min-width: 560px) {
  .closing-media { aspect-ratio: 16 / 9; }
  .closing .act { justify-items: start; }
  .closing .act .btn { width: auto; }
  .closing .fine { text-align: left; }
  .cover-act { justify-items: start; }
  .cover-act .btn { width: auto; }
  .cover-six { justify-content: flex-start; }
  .bags { grid-template-columns: repeat(2, 1fr); }
  .pockets > div { grid-template-columns: 11.5em 1fr; align-items: baseline; }
  .footer .cols { grid-template-columns: 2fr 1fr 1fr 1fr; justify-content: normal; column-gap: 32px; }
  .footer .about { grid-column: auto; }
}

/* ============================================================== 760 and up */
@media (min-width: 760px) {
  .promises { grid-template-columns: repeat(4, 1fr); }
  .promises li { padding: 38px 22px 34px; }
  .promises li + li { border-left: 1px solid var(--line-soft); }
  .promises li:nth-child(n + 3) { border-top: 0; }
  .quotes h2 { margin-bottom: 48px; }
  .manifesto .say { line-height: 1.16; }
  .footer .top { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(32px, 5vw, 80px); align-items: end; }
}

/* ============================================================== 900 and up */
@media (min-width: 900px) {
  .closing { position: relative; display: block; height: clamp(500px, 37.71vw, 860px); overflow: hidden; }
  .closing-media { position: absolute; inset: 0; aspect-ratio: auto; }
  .closing-media img { object-position: 30% 50%; }
  /* the stone behind the words is lifted a touch, so small type reads cleanly over its texture */
  .closing::before { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(90deg, rgba(247, 245, 241, 0.52) 0%, rgba(247, 245, 241, 0.4) 26%, rgba(247, 245, 241, 0) 46%); }
  .closing-copy { z-index: 2; }
  .closing .sub, .closing .fine { color: var(--ink); }
  /* the words stand on the content column, in line with the footer beneath them */
  .closing-copy { position: absolute; inset: 0; max-width: var(--max); margin: 0 auto; padding: 0 var(--pad); display: flex; flex-direction: column; justify-content: center; align-items: flex-start; }
  .closing h2 { max-width: 10.5em; }
  .closing .sub { max-width: 23em; }
  .closing .act { margin-top: clamp(24px, 3.4vw, 40px); justify-items: start; gap: 14px; }

  .mast .brand img { height: 38px; }
  .mast a.desk { display: inline-flex; }
  .mast button.phone { display: none; }

  .cover-pager { bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
  /* (C2, 26 Oct) The words have presence: the headline grows with the window (to 120px), held by its height so a short
     window never crowds (about 86px at 1920x1080, 79px at 1912x880, 65px at 1440x900), and the kicker, the line under
     it, the button and the dots step up with it. The column is as wide as the headline's longer line (7.9em of it,
     "Goes everywhere," being 7.7em), so the photograph can come close; the group stands in the middle of the height
     below the header, level with the bag (the script after the opening sets the bag to meet it). */
  .cover { --h1: clamp(34px, min(4.5vw, 9vh), 120px); }
  .cover-copy { left: max(var(--pad), 8.9vw); right: auto; width: calc(var(--h1) * 7.9); top: var(--mast); bottom: calc(var(--h1) * 0.3); display: flex; flex-direction: column; justify-content: center; }
  .cover h1 { margin-top: calc(var(--h1) * 0.16); }
  .cover-sub { margin-top: calc(var(--h1) * 0.3); max-width: 23em; }
  [data-cover] .cover-sub { display: block; }
  .cover-act { margin-top: calc(var(--h1) * 0.52); display: flex; align-items: center; flex-wrap: wrap; gap: 14px 26px; }


  .shop-head { grid-template-columns: 1fr minmax(0, 31em); gap: clamp(32px, 5vw, 80px); align-items: end; padding-bottom: 36px; }
  .bags { grid-template-columns: repeat(3, 1fr); gap: 72px clamp(24px, 3.2vw, 44px); margin-top: 44px; }
  .bag-line { min-height: 4.65em; }

  .makers-grid { grid-template-columns: 3fr 2fr 2fr; gap: 0 clamp(14px, 1.7vw, 22px); grid-template-areas: "a b c" "head body body"; }
  .m-a .ph, .m-b .ph, .m-c .ph { aspect-ratio: auto; height: clamp(380px, 38vw, 540px); }
  .m-head { margin: clamp(44px, 5vw, 68px) 0 0; max-width: 10em; }
  .m-body { padding: clamp(48px, 5.4vw, 74px) 0 0; }
  .m-body .share { margin-top: 24px; }

  .anatomy { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(32px, 5vw, 72px); align-items: center; }
  .open-line { font-size: var(--t-h3); }
  .pockets > div { grid-template-columns: 1fr; }

  .ways { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(40px, 6vw, 104px); align-items: center; }
  .ways-words { display: block; }
  .ways-grid { margin-top: 32px; }
  .ways-grid li { padding: 20px 20px 22px 0; }
  .ways-grid li:nth-child(even) { padding: 20px 0 22px 22px; }
  .field-notes { margin-top: 40px; }
  .wild-head { margin-bottom: 48px; }
  .wear { grid-template-columns: repeat(4, 1fr); gap: clamp(16px, 2vw, 28px); }

  /* the process: the head splits (label and heading left, her paragraph right, in the viewer's columns), then one row of five */
  .making-head { display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); column-gap: clamp(48px, 6.5vw, 112px); grid-template-rows: auto 1fr; align-items: start; margin-bottom: clamp(44px, 4.4vw, 64px); }
  .making-head .label { grid-column: 1; grid-row: 1; }
  .making-head h2 { grid-column: 1; grid-row: 2; }
  .making-head p:not(.label) { grid-column: 2; grid-row: 1 / 3; margin-top: 0; max-width: none; }
  .steps-wrap { container-type: inline-size; --cut: 0 100% 0 0; }
  .steps { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0 var(--sg); align-items: start; }
  .steps figure { display: block; }
  .steps figcaption { margin: 34px auto 0; text-align: center; }
  .steps-wrap > .thread { left: 0; right: 0; bottom: auto; width: auto; height: 1.5px; top: calc((100cqw - 4 * var(--sg)) * 4 / 15 + 16px); background: repeating-linear-gradient(90deg, currentColor 0 4px, transparent 4px 7px); }

  .drawer .panel { left: auto; top: 0; bottom: 0; width: min(440px, 100%); max-height: none; border-left: 1px solid var(--line); transform: translateX(100%); padding: 22px 32px 28px; }
}

/* ============================================================= 1200 and up */
@media (min-width: 1200px) {
  .pockets > div { grid-template-columns: 11.5em 1fr; }
  .specs { grid-template-columns: repeat(4, auto); justify-content: space-between; }
}

/* (C2) The opening's smaller words, the button and the dots step up with its headline, on the type scale: the kicker
   to the subhead size and the line under it to the lead from 1440, the line to the subhead size, the button's and the
   dots' words to the small size from 1800; the button and the dots grow with them. */
@media (min-width: 1440px) {
  .cover-kicker { font-size: var(--t-h3); }
  .cover-sub { font-size: var(--t-lead); }
  .cover-act { gap: 14px 30px; }
  .cover-act .btn { height: 56px; padding: 0 30px; }
  .cover-six .dots a { width: 27px; }
  .cover-six .dots a::before { width: 13px; height: 13px; }
}
@media (min-width: 1800px) {
  /* a large screen (2560x1440) is filled to the foot, as a smaller one is: the opening is no longer held at 1080 */
  .cover { max-height: 1440px; }
  /* past 21px the kicker is part of the heading: it grows with the headline, as the button does */
  .cover-kicker { font-size: max(var(--t-h3), calc(var(--h1) * 0.25)); }
  .cover-sub { font-size: var(--t-h3); }
  .cover-act .btn { height: clamp(62px, calc(var(--h1) * 0.62), 74px); padding: 0 clamp(34px, calc(var(--h1) * 0.36), 44px); gap: 18px; font-size: var(--t-small); }
  .cover-act .btn .price { padding-left: 18px; }
  .cover-six { font-size: var(--t-small); }
  .cover-six .dots a { width: 30px; }
  .cover-six .dots a::before { width: 14px; height: 14px; }
}

/* the three notes side by side once each can be a phone's width */
@media (min-width: 1000px) {
  .notes { grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 2.6vw, 36px); align-items: stretch; }
  .notes > li { width: auto; }
  .screen { min-height: 340px; }
}

/* a hand on a mouse: the bag lifts a little; if it has a second picture, that takes its place */

/* ---------------------------------------------------------- reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .cover-media, .cover h1 .ln > span, .cover-kicker, .cover-sub, .cover-act, .cover-pager { animation: none; }
  .slide, .slide.is-on, .slide.was-on, .cover-kicker, .cover h1, .cover-sub, .cover-six, .cover-pager, .cover-pager svg, .dots a::before { transition: none !important; }
  .ticker .track { animation: none; width: 100%; justify-content: center; }
  .ticker span + span, .ticker span::after { display: none; }
  .mast, .mast .brand img, .bag-shot .swatch, .bag-view, .bag-view .render, .bag-meta::before, .btn, .link { transition-duration: 0ms !important; }
  .drawer .panel { transform: none; opacity: 0; transition: opacity 200ms; }
  .drawer.is-open .panel { opacity: 1; }
  .drawer.is-open .panel > * { transition-delay: 0ms; }
}


/* Editorial refinement: quieter product gallery and clearer purchasing hierarchy. */
.bag-meta::before { display: none; }
.bag-meta { border-top-color: var(--line); padding-top: 20px; }
.bag-shot { cursor: default; }
.bag-shot .render { transition-duration: 620ms, 900ms; }
.bag-name { font-size: var(--t-name); letter-spacing: -0.025em; }
.bag-price { color: var(--soft); font-size: var(--t-body); }
.bag-fin { margin-top: 8px; }
.bag-line { max-width: 29ch; line-height: 1.55; margin-top: 13px; }
.bag-buy { margin-top: 22px; box-shadow: none; border-bottom: 1px solid currentColor; padding: 0 0 5px; height: auto; min-height: 36px; letter-spacing: 0.12em; }
.bag-buy:hover { background: transparent; color: var(--ink); }
.bag-buy:focus-visible { outline: 2px solid var(--ink); outline-offset: 5px; }
@media (hover: hover) and (pointer: fine) {
  .bag:hover .bag-shot:not(.has-second) .render { transform: translateY(-50%) scale(1.018); }
}
@media (prefers-reduced-motion: reduce) {
  .bag-shot .render, .bag-buy { transition: none !important; }
}

/* ---------------------------------------------------------- colour bands */
/* A band is a full-width ground of its own colour that holds one section or a few. Its inner .wrap keeps the
   column; --band-pad is the space above the first and below the last content. */
.band { position: relative; width: 100%; margin-top: var(--gap); padding-block: var(--band-pad); }
.band + .band { margin-top: 0; }
.band--navy { background: var(--navy); color: var(--on-navy); }
.band--powder { background: var(--powder); }

/* ------------------------------------------------------------ interactions */
/* Alive under the hand, never busy (spec section 5). Hovers 200 to 320ms on the arrival ease; a hover transform waits
   for the arrival to be done (.is-done) and touch screens, which have no hover, are left out. */

/* bag cards: the whole card answers. The picture eases in its frame and the arrow steps forward; the name carries no
   underline (Gautam, 26 Oct). */
.bag-buy::after { content: ""; flex: none; width: 15px; height: 9px; margin-left: 12px; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 9'%3E%3Cpath d='M0 4.5h14M10.2 .8 14 4.5l-3.8 3.7' fill='none' stroke='black' stroke-width='1.1'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 15 9'%3E%3Cpath d='M0 4.5h14M10.2 .8 14 4.5l-3.8 3.7' fill='none' stroke='black' stroke-width='1.1'/%3E%3C/svg%3E") center / contain no-repeat; transition: transform 320ms var(--ease); }
.bag:has(:focus-visible) .bag-buy::after { transform: translateX(3px); }
@media (prefers-reduced-motion: no-preference) {
  .bag-shot .swatch { transition: transform 320ms var(--ease); }
  .bag.is-done:has(:focus-visible) .bag-shot .swatch { transform: scale(1.04); }
  @media (hover: hover) and (pointer: fine) {
    .bag.is-done:hover .bag-shot .swatch { transform: scale(1.04); }
    .bag:hover .bag-buy::after { transform: translateX(3px); }
  }
}
@media (prefers-reduced-motion: reduce) {
  .bag-buy::after { transition: none; }
}

/* Notes & Quotes: a screen lifts a little, its shadow deepens */
.screen { transition: transform 320ms var(--ease), box-shadow 320ms var(--ease); }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .note:hover .screen { transform: translateY(-6px); box-shadow: 0 0 0 1px rgba(17, 26, 59, 0.07), 0 34px 60px -28px rgba(17, 26, 59, 0.5); }
}

/* In the Wild and the five steps: each photograph eases in its frame (the picture's own develop uses scale, this uses transform) */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .wear [data-ph].is-done img, .steps [data-ph].is-done img { transition: transform 320ms var(--ease); }
  .wear [data-ph].is-done:hover img, .steps [data-ph].is-done:hover img { transform: scale(1.03); }
}

/* sign-up: the line under the email field darkens and draws to full width on focus (currentColor, so it follows the ground) */
.footer form::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: 0 50%; transition: transform 420ms var(--ease); }
.footer form:focus-within::after { transform: scaleX(1); }
@keyframes note-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: no-preference) {
  .footer .fine.is-done { animation: note-in 700ms var(--ease) both; }
}
@media (prefers-reduced-motion: reduce) {
  .footer form::after { transition: none; }
}

/* ---------------------------------------------------------------- the shop, live (js/shop.js, js/app.js)
   The sign-up's hidden field (people never see it; anything typed there is a bot), a leather that has sold
   out, and Allie's latest Instagram posts under In the Wild: six small squares in the column, a row on wide
   screens and three across on a phone, hidden until they arrive. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.bag.is-sold-out .tag, .bag.is-sold-out .bag-buy { color: var(--quiet); }
.bag.is-sold-out .bag-buy { pointer-events: none; }
.buy-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.insta { margin-top: clamp(56px, 7vw, 96px); }
.insta-head { text-align: center; font-family: var(--serif); font-size: var(--t-lead); line-height: 1.3; color: var(--soft); }
.insta-head a { color: var(--ink); background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; padding-bottom: 2px; transition: background-size 420ms var(--ease); }
.insta-head a:hover { background-size: 0 1px; background-position: 100% 100%; }
.insta-grid { list-style: none; padding: 0; margin-top: 20px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.insta-grid a { display: block; }
.insta-grid .ph { display: block; aspect-ratio: 1; overflow: hidden; background: var(--line-soft); }
.insta-grid img { width: 100%; height: 100%; object-fit: cover; transition: transform 320ms var(--ease); }
.insta-grid a:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
@media (hover: hover) { .insta-grid a:hover img { transform: scale(1.03); } }
@media (min-width: 760px) { .insta-grid { grid-template-columns: repeat(6, 1fr); gap: clamp(8px, 1vw, 14px); } }
@media (prefers-reduced-motion: reduce) { .insta-grid img, .insta-head a { transition: none; } }
