/* ==========================================================================
   Kenny Jones Designs
   Structural design system modelled on the Tundra reference capture.
   Token values and ratios are documented in .claude/design-system.md
   ========================================================================== */

/* ---------- Tokens ---------- */
:root {
  --bg:         #0B0B0B;
  --surface:    #111111;
  --text:       #FFFFFF;
  --muted:      #A0A0A0;
  --accent:     #BFD7FF;
  --on-accent:  #0B0B0B;
  --hairline:   rgba(255, 255, 255, 0.10);
  --divider:    #1F1F1F;

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  --nav-h:      48px;
  --gutter:     24px;
  --section-y:  64px;

  --ease:       cubic-bezier(0.44, 0, 0.56, 1);
  --ease-out:   cubic-bezier(0.12, 0.23, 0.5, 1);
  --fade:       opacity 0.3s ease;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 12px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p { margin: 0; }

/* Nothing in this system is rounded. */
* { border-radius: 0; }

/* ---------- Typography ---------- */
.t-display {
  font-size: 64px;
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.15;
}

.t-section {
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.t-lead {
  font-size: 18px;
  font-weight: 400;
  line-height: 1.55;
}

.t-label {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.t-label-wide {
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.t-link {
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.1;
}

.t-muted { color: var(--muted); }

/* ---------- Layout ---------- */
.wrap { padding-inline: var(--gutter); }

.section { padding-block: var(--section-y); }
.section--flush { padding-block: 0; }

/* The header pins under the nav and stays for the whole section, so the
   plate slides up behind it rather than the section losing its label. */
.section-head {
  position: sticky;
  top: var(--nav-h);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: var(--gutter);
  background: var(--surface);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 12px 24px;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.1;
  transition: var(--fade);
}

.btn--accent { background: var(--accent); color: var(--on-accent); }
.btn--accent:hover { opacity: 0.82; }

.btn--ghost { border: 1px solid var(--hairline); color: var(--text); }
.btn--ghost:hover { border-color: var(--text); }

/* ==========================================================================
   Preloader
   Full-screen wordmark on the canvas colour, holds scroll until released.
   ========================================================================== */
/* Two half-width panels stand in for the canvas-colour background and part
   like stage curtains on exit. Closing (entrance) is instant - a visitor
   should never see the raw page flash before the preloader covers it - so
   only the `body.is-ready` state below carries a transition. Default
   position is open (off-screen), so a no-JS visitor is never left staring
   at an opaque overlay that nothing will ever dismiss. */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 999;
  /* No visual of its own (the curtains carry that) - never block clicks
     on the real page underneath once they've parted. */
  pointer-events: none;
}

.preloader__curtain {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  /* Repeating vertical pleats (fixed px, not %, so the fold width reads the
     same physical size at any viewport) layered over a gentle top-to-bottom
     shade for depth, on top of the canvas colour. */
  background:
    repeating-linear-gradient(
      90deg,
      rgba(255, 255, 255, 0.05) 0px,
      rgba(255, 255, 255, 0.05) 3px,
      rgba(255, 255, 255, 0.015) 10px,
      rgba(0, 0, 0, 0.16) 20px,
      rgba(0, 0, 0, 0.26) 28px,
      rgba(0, 0, 0, 0.16) 36px,
      rgba(255, 255, 255, 0.015) 46px,
      rgba(255, 255, 255, 0.05) 53px
    ),
    linear-gradient(180deg, rgba(255, 255, 255, 0.04) 0%, rgba(0, 0, 0, 0.1) 100%),
    var(--bg);
  /* Opts back in to blocking while it's actually covering the page. */
  pointer-events: auto;
}
.preloader__curtain--left {
  left: 0;
  transform: translateX(-100%);
  box-shadow: inset -14px 0 24px rgba(0, 0, 0, 0.45);
}
.preloader__curtain--right {
  right: 0;
  transform: translateX(100%);
  box-shadow: inset 14px 0 24px rgba(0, 0, 0, 0.45);
}

body.js:not(.is-ready) .preloader__curtain { transform: translateX(0); }

body.is-ready .preloader__curtain { transition: transform 1.1s cubic-bezier(0.22, 1, 0.36, 1); }
body.is-ready .preloader__curtain--left { transform: translateX(-100%); }
body.is-ready .preloader__curtain--right { transform: translateX(100%); }

.preloader__mark {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  transition: opacity 0.35s ease;
}

body.is-ready .preloader__mark { opacity: 0; }

.preloader__eyebrow {
  margin: 0;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  opacity: 0;
  transform: translateY(10px);
  animation: preloadRise 0.5s var(--ease-out) forwards;
}

.preloader__wordmark {
  margin: 0;
  text-align: center;
  font-family: var(--font);
  font-weight: 700;
  line-height: 0.9;
  letter-spacing: -0.03em;
  text-transform: uppercase;
}

.preloader__line {
  display: block;
  font-size: clamp(48px, 9vw, 120px);
  opacity: 0;
  transform: translateY(28px) scale(0.95);
  animation: preloadRise 0.6s var(--ease-out) forwards;
}
.preloader__line--1 { color: var(--text); animation-delay: 0.1s; }
.preloader__line--2 { color: var(--accent); animation-delay: 0.28s; }

@keyframes preloadRise {
  to { opacity: 1; transform: none; }
}

body.is-loading { overflow: hidden; }

/* ==========================================================================
   Nav
   A segmented bar: cells divided by 1px rules, with the link and promo cells
   sitting a shade lighter than the bar itself. The promo marquee lives here
   rather than as a separate strip further down the page.
   ========================================================================== */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  display: flex;
  height: var(--nav-h);
  background: var(--bg);
}

.nav__cell {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-left: 1px solid var(--divider);
}
.nav__cell:first-child { border-left: 0; }

.nav__brand {
  padding: 0 16px;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text);
}

/* Full name at desktop; below 768px it crowds the Shop/Lookbook cells down
   to a width narrower than their own text (see the mobile breakpoint,
   where the short form takes over). */
.nav__brand-short { display: none; }

.nav__time {
  gap: 8px;
  padding: 0 13px;
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
}
.nav__time span:nth-child(2) { color: var(--muted); }
.nav__time span:nth-child(3) { color: var(--text); }

/* The two links and the promo split the remaining width 1 : 1 : 2, which is
   the 234 / 234 / 469 the reference resolves to at 1280. */
.nav__link {
  flex: 1 1 0;
  min-width: 0;
  background: var(--surface);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: var(--fade);
}
.nav__link:hover, .nav__link.is-active { background: #191919; }

/* Shop is a link and a hover-revealed flyout, not a click-toggled dropdown:
   the link stays fully functional with no JS, the flyout is a pure-CSS
   enhancement on top, matching the "content still appears if JS fails"
   discipline the rest of this system's motion follows. */
.nav__link--shop { position: relative; padding: 0; }

.nav__link-hit {
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: center;
}

.nav__mega {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 50;
  display: flex;
  align-items: flex-start;
  background: var(--surface);
  border-top: 1px solid var(--divider);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease), visibility 0.25s;
}

.nav__link--shop:hover .nav__mega,
.nav__link--shop:focus-within .nav__mega {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.nav__mega-col {
  padding: var(--gutter);
  min-width: 160px;
  border-left: 1px solid var(--divider);
}
.nav__mega-col:first-child { border-left: 0; }
.nav__mega-col .t-label { margin-bottom: 12px; }

.nav__mega-link {
  display: block;
  padding: 6px 0;
  font-size: 13px;
  color: var(--text);
  white-space: nowrap;
  transition: var(--fade);
}
.nav__mega-link:hover { opacity: 0.6; }

.nav__mega-feature {
  position: relative;
  width: 160px;
  aspect-ratio: 2 / 3;
  flex-shrink: 0;
  overflow: hidden;
}
.nav__mega-feature img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }
.nav__mega-feature .t-label {
  position: absolute;
  left: 12px;
  bottom: 12px;
  color: var(--text);
}

.nav__promo {
  flex: 2 1 0;
  min-width: 0;
  overflow: hidden;
  background: var(--surface);
}

.nav__promo-track {
  display: flex;
  width: max-content;
  animation: tickerScroll 40s linear infinite;
}
.nav__promo:hover .nav__promo-track { animation-play-state: paused; }

.nav__promo-item {
  display: inline-flex;
  align-items: center;
  gap: 40px;
  padding-inline: 20px;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}

.nav__promo-dot { width: 3px; height: 3px; background: var(--muted); flex-shrink: 0; }

.nav__cart {
  gap: 8px;
  padding: 0 16px;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: var(--fade);
}
.nav__cart:hover { opacity: 0.7; }

.nav__count {
  min-width: 16px;
  height: 16px;
  display: inline-grid;
  place-items: center;
  padding-inline: 4px;
  background: var(--text);
  color: var(--bg);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: normal;
  line-height: 1;
}

.nav__search { width: 44px; }
.nav__search svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.5; }

@keyframes tickerScroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ==========================================================================
   Hero
   Full-viewport image, content bottom-left, variant selector bottom-right.
   ========================================================================== */
.hero {
  position: relative;
  height: calc(100vh - var(--nav-h));
  min-height: 560px;
  margin-top: var(--nav-h);
  overflow: hidden;
}

.hero__media { position: absolute; inset: 0; }

.hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Biased upward so faces survive the crop on the portrait-shaped frames. */
  object-position: center 30%;
  opacity: 0;
  transition: opacity 1s var(--ease);
}
.hero__img.is-active { opacity: 1; }

.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(8, 16, 38, 0.82) 0%, rgba(8, 16, 38, 0.48) 45%, rgba(8, 16, 38, 0.2) 100%);
}

.hero__inner {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  padding: var(--gutter);
}

.hero__content { max-width: 440px; }
.hero__content > * + * { margin-top: 16px; }
.hero__copy { max-width: 400px; }

.hero__selector { display: flex; gap: 8px; }

.hero__thumb {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 90px;
  padding: 0;
  opacity: 0.5;
  transition: var(--fade);
}
.hero__thumb img {
  display: block;
  width: 100%;
  height: 60px;
  object-fit: cover;
  border: 1px solid transparent;
  transition: border-color 0.3s ease;
}
.hero__thumb:hover { opacity: 0.8; }
.hero__thumb.is-active { opacity: 1; }
.hero__thumb.is-active img { border-color: var(--text); }

/* Its own line above the thumbnail, not an overlay on top of it. */
.hero__thumb-progress {
  display: block;
  width: 100%;
  height: 2px;
  background: rgba(255, 255, 255, 0.35);
}
.hero__thumb-progress-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--text, #fff);
}
@keyframes heroProgress {
  from { width: 0%; }
  to   { width: 100%; }
}

/* ==========================================================================
   Marquee ticker
   ========================================================================== */
/* ==========================================================================
   Tabbed rail
   Two centred tabs acting as the section header, over an endless marquee of
   fixed-width cards that runs off the right edge.
   ========================================================================== */
.tabs {
  display: flex;
  justify-content: center;
  gap: 1px;
  padding: 80px 0 64px;
}

.tab {
  width: 200px;
  height: 38px;
  background: var(--surface);
  color: var(--muted);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: var(--fade), background-color 0.3s ease, color 0.3s ease;
}
.tab:hover { color: var(--text); }
.tab.is-active { background: var(--text); color: var(--on-accent); }

.rail { overflow: hidden; }

/* The row never ends: the card set is emitted twice and the track slides by
   exactly half its width, so the seam is invisible. */
.rail__track {
  display: flex;
  gap: 3px;
  width: max-content;
  animation: railScroll 70s linear infinite;
}
.rail__track[hidden] { display: none; }
.rail:hover .rail__track { animation-play-state: paused; }

.rail .card { flex: 0 0 300px; width: 300px; }

/* Touch devices have no hover, so the auto-scroll never pauses and the rail
   (overflow: hidden) can't be swiped either - it just runs on its own with
   no way to stop and look at a card. Hand control to the user instead: stop
   the animation and let them swipe. The doubled card list (see comment
   above) means swiping all the way through repeats the same 6 cards, which
   matches the "endless" intent of the desktop marquee rather than breaking it. */
@media (hover: none) {
  .rail__track { animation: none; }
  .rail {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
  }
  .rail .card { scroll-snap-align: start; }
}

@keyframes railScroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ==========================================================================
   Product grid and card
   Zero gutter. Cards sit edge to edge, image is 2:3 portrait.
   ========================================================================== */
.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 3px;
}

/* A category section is two halves: a plate that stays put while the three
   rows of products beside it scroll past, then releases into the next
   section. The plate alternates sides down the page: left, right, left. */
.split-section {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
}

.split-section__cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 3px;
}

.split-section--right .split-section__plate { order: 2; }

.editorial {
  position: sticky;
  top: calc(var(--nav-h) + 23px);
  display: block;
  /* Full viewport height, so the pinned plate always runs to the bottom of
     the screen instead of stopping short and leaving a dead band beneath. */
  height: 100vh;
  overflow: hidden;
}

.editorial img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  transition: transform 1.2s var(--ease);
}
.editorial:hover img { transform: scale(1.04); }

.card { position: relative; display: block; }
.card__link { position: absolute; inset: 0; z-index: 1; }

.card__media {
  position: relative;
  aspect-ratio: 2 / 3;
  overflow: hidden;
  background: var(--surface);
}

.card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 0.5s var(--ease), transform 1.2s var(--ease);
}

.card__img--alt { opacity: 0; }
.card:hover .card__img--alt { opacity: 1; }
.card:hover .card__img--main { opacity: 0; }

/* Single-image cards (coming-soon teaser grid) get a slow push-in instead of
   a swap - there is no second image to cross-fade to. */
.card--single:hover .card__img--main { transform: scale(1.05); opacity: 1; }

.card__badge {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 2;
  padding: 4px 8px;
  background: var(--bg);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Sits bottom-right inside the image with a 16px inset, dark rather than
   white, label left and a plus glyph right. Revealed on hover. */
.card__quick {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 2;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 136px;
  height: 40px;
  padding: 0 16px;
  background: var(--surface);
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity 0.3s ease, color 0.3s ease;
}

.card__quick::after {
  content: "+";
  font-size: 14px;
  line-height: 1;
}

.card:hover .card__quick { opacity: 1; }
.card__quick:hover { color: var(--text); }

.card__body { padding: 16px; }
.card__name { font-size: 14px; line-height: 1.4; color: var(--muted); }
.card__price { margin-top: 4px; font-size: 13px; font-weight: 500; line-height: 1; }

/* ==========================================================================
   Footer
   ========================================================================== */
/* Geometry mirrors the reference: two stacked bands of three equal columns,
   each column inset 40px, with the newsletter living inside the link band
   as its third column rather than as a separate section above the footer. */
.footer { background: var(--surface); padding-top: 48px; }

/* 40px both sides gives the 347px content measure the reference uses. */
.footer__inset { padding: 0 40px; }

/* Band one: brand column plus two image plates */
.footer__content { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; }

.footer__brand { display: flex; flex-direction: column; }
.footer__brand-inner { flex: 1; padding: 0 40px; }

/* Stacked so the wordmark can carry the same weight the reference's does.
   On one line, nineteen characters cannot get large in a 347px column. */
.footer__logo {
  font-size: 44px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.02;
}
.footer__logo span { display: block; }

.footer__blurb { margin-top: 40px; max-width: 347px; font-size: 14px; line-height: 1.4; color: var(--muted); }
.footer__copyright { margin-top: 20px; font-size: 12px; line-height: 1.4; color: var(--muted); }

.footer__plate { position: relative; aspect-ratio: 427 / 265; overflow: hidden; }
.footer__plate img { width: 100%; height: 100%; object-fit: cover; }

/* Social row sits flush at the base of the brand column, four equal cells
   separated by a 1px seam of the footer surface showing through. */
.footer__social { display: flex; gap: 1px; }

.footer__social a {
  flex: 1;
  height: 40px;
  display: grid;
  place-items: center;
  background: var(--bg);
  transition: var(--fade);
}
.footer__social a:hover { opacity: 0.6; }
.footer__social svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.5; }

/* Band two: two link columns plus the newsletter */
.footer__links {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding-block: 40px;
}

.footer__group + .footer__group { margin-top: 40px; }

.footer__group h4 {
  margin-bottom: 16px;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.55;
  color: var(--accent);
}

.footer__group li + li { margin-top: 15px; }

.footer__group a {
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--muted);
  transition: var(--fade);
}
.footer__group a:hover { color: var(--text); }

.footer__news-copy { margin-top: 16px; max-width: 347px; }
.footer__form { margin-top: 80px; max-width: 347px; }

.footer__form label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.3;
}

.footer__form input {
  width: 100%;
  height: 40px;
  margin-top: 9px;
  padding: 12px;
  background: rgba(187, 187, 187, 0.15);
  border: 0;
  color: var(--text);
  font: inherit;
  font-size: 13px;
}
.footer__form input::placeholder { color: rgb(153, 153, 153); }
.footer__form input:focus { outline: 1px solid var(--accent); outline-offset: -1px; }

.footer__form button {
  width: 100%;
  height: 40px;
  margin-top: 8px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 12px;
  transition: var(--fade);
}
.footer__form button:hover { opacity: 0.82; }

/* ==========================================================================
   Entrance motion
   Mirrors the reference: opacity 0.001 to 1 with a 20px rise, staggered.
   ========================================================================== */
/* Content is visible by default. Only once JS confirms it can drive the
   reveal do elements start hidden, so a JS failure never buries the page. */
.rise { opacity: 1; }

body.js .rise {
  opacity: 0.001;
  transform: translateY(20px);
}

body.js.is-ready .rise.is-in,
body.js.is-ready .hero .rise {
  opacity: 1;
  transform: none;
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}

.rise-1 { transition-delay: 0.1s; }
.rise-2 { transition-delay: 0.2s; }
.rise-3 { transition-delay: 0.3s; }
.rise-4 { transition-delay: 0.4s; }

@media (prefers-reduced-motion: reduce) {
  .rise { opacity: 1; transform: none; }
  .nav__promo-track, .rail__track { animation: none; }
  .rail { overflow-x: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1024px) {
  .t-display { font-size: 48px; }
  .grid { grid-template-columns: repeat(3, 1fr); }
  .editorial { height: 100vh; }
}

@media (max-width: 768px) {
  :root { --section-y: 48px; }

  /* Only two links, so they stay in the bar; the time, promo and search
     cells drop away. The brand shrinks and the cart keeps just its count, so
     the four remaining cells always fit without competing for width. */
  .nav__time, .nav__promo, .nav__search, .nav__cart-label { display: none; }
  .nav__brand { padding: 0 var(--gutter); font-size: 12px; }
  .nav__brand-full { display: none; }
  .nav__brand-short { display: inline; }
  .footer__logo { font-size: 34px; }
  .nav__link { font-size: 12px; }
  /* No hover on touch and no room for a flyout at this width - Shop stays a
     plain link straight into /collections. */
  .nav__mega { display: none; }
  .nav__cart { padding: 0 var(--gutter); }

  .t-display { font-size: 36px; }
  .t-section { font-size: 24px; }
  .t-lead { font-size: 16px; }

  .hero__inner { flex-direction: column; align-items: flex-start; }
  .hero__selector { align-self: flex-start; }
  .hero__thumb { width: 64px; }
  .hero__thumb img { height: 44px; }

  .grid { grid-template-columns: repeat(2, 1fr); }
  .split-section { grid-template-columns: 1fr; }
  .split-section--right .split-section__plate { order: 0; }
  .editorial { position: static; height: auto; aspect-ratio: 4 / 3; }

  .card__quick { opacity: 1; width: calc(100% - 32px); }

  .footer__content,
  .footer__links { grid-template-columns: 1fr; }
  .footer__brand-inner { padding: 0 var(--gutter); }
  .footer__links { padding: 40px var(--gutter) 0; }
  .footer__col + .footer__col { margin-top: 40px; }
  .footer__form { margin-top: 40px; }
  .footer__plate { aspect-ratio: 3 / 2; }
}

/* ==========================================================================
   Inner page components
   ========================================================================== */

.page-head {
  padding: calc(var(--nav-h) + 80px) var(--gutter) 48px;
  border-bottom: 1px solid var(--hairline);
}

.page-head__title { max-width: 720px; }
.page-head__copy { max-width: 520px; margin-top: 16px; }

/* Category filter row */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  padding: 24px var(--gutter);
  border-bottom: 1px solid var(--hairline);
}

.filters a {
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  transition: var(--fade);
}
.filters a:hover, .filters a.is-active { color: var(--text); }

/* Text column */
.prose { max-width: 640px; }
.prose > * + * { margin-top: 16px; }
.prose p { font-size: 18px; line-height: 1.55; color: var(--muted); }

/* Image and text split, zero gutter like the product grids */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  align-items: stretch;
}

.split__media { position: relative; min-height: 480px; overflow: hidden; }
.split__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.split__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 64px var(--gutter);
  background: var(--surface);
}
.split__body > * + * { margin-top: 16px; }
.split--flip .split__media { order: 2; }

/* Numbered process steps */
.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  border-top: 1px solid var(--hairline);
}

.step {
  padding: 40px var(--gutter);
  border-right: 1px solid var(--hairline);
}
.step:last-child { border-right: 0; }
.step__num { font-size: 30px; font-weight: 600; letter-spacing: -0.02em; color: var(--accent); }
.step__title { margin-top: 16px; font-size: 18px; font-weight: 500; }
.step__copy { margin-top: 8px; font-size: 14px; line-height: 1.5; color: var(--muted); }

/* Editorial image grid for the lookbook. Caption sits below the frame as
   its own row (title left, season tag right) rather than overlaid on the
   image, so it stays fully legible against any photograph. */
.plate-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; }
.plate { display: flex; flex-direction: column; }
.plate__media { position: relative; overflow: hidden; aspect-ratio: 2 / 3; }
.plate__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease); }
.plate:hover .plate__media img { transform: scale(1.04); }

.plate__caption {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 16px var(--gutter);
  background: var(--bg);
}
.plate__title {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text);
}
.plate__meta {
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

/* Catalog bento gallery (zicstack/kj-website#15) - a size-varied grid used
   by /catalog and /catalog/<category>, alongside (not replacing) .plate-grid
   above, which nothing references now that the lookbook route is gone but
   is left in place rather than deleted along with an unrelated change. */
.bento {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 160px;
  grid-auto-flow: dense;
  gap: 3px;
}
.bento__item {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  cursor: pointer;
  border: 0;
  padding: 0;
  text-align: left;
  background: none;
}
.bento__item--lg { grid-column: span 2; grid-row: span 3; }
.bento__item--md { grid-column: span 2; grid-row: span 2; }
.bento__item--sm { grid-column: span 1; grid-row: span 2; }

/* Media fills whatever height is left once .bento__caption below takes its
   own row, so the grid cell's total height still matches its row-span. */
.bento__media { position: relative; flex: 1; min-height: 0; overflow: hidden; }

.bento__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Portrait/people photography - biased up so heads survive the crop,
     same fix already applied to the footer plates and the homepage hero. */
  object-position: center top;
  transition: transform 1.2s var(--ease);
}
.bento__item:hover .bento__img { transform: scale(1.04); }

/* Heart/like toggle (zicstack/kj-website#24) - always present, no separate
   "selection mode": tapping it saves the look without opening the detail
   view; the rest of the tile still opens the lightbox as before. */
.like-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 1;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  background: rgba(11, 11, 11, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.2);
}
.like-btn svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: var(--text);
  stroke-width: 1.5;
  transition: fill 0.15s ease, stroke 0.15s ease;
}
.like-btn:hover svg { stroke: var(--accent); }
.like-btn.is-liked svg { fill: var(--accent); stroke: var(--accent); }

.bento__caption {
  flex-shrink: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: var(--bg);
}
.bento__title {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text);
}
.bento__tag {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}

/* Catalog item detail view, opened from a .bento__item click. Centered
   modal (rather than the .cart edge drawer) since it presents a single
   large image, not a list. */
.lightbox-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  opacity: 0;
  visibility: hidden;
  transition: var(--fade);
  z-index: 300;
}
.lightbox-scrim.is-open { opacity: 1; visibility: visible; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 301;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(280px, 0.6fr);
  width: 90vw;
  max-width: 1100px;
  height: fit-content;
  max-height: 80vh;
  margin: auto;
  background: var(--surface);
  border: 1px solid var(--hairline);
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out), visibility 0.3s;
  pointer-events: none;
}
.lightbox.is-open { opacity: 1; visibility: visible; transform: none; pointer-events: auto; }

.lightbox__media { position: relative; overflow: hidden; background: var(--bg); min-height: 320px; }
.lightbox__media img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }

/* flex-start + the button's own margin-top: auto (see CatalogGallery.tsx)
   spans the label/title/button across the panel's full height - matching
   the image beside it - instead of floating as one centered block with
   large empty margins top and bottom. */
.lightbox__body { display: flex; flex-direction: column; justify-content: flex-start; padding: var(--gutter); }

.lightbox__close {
  position: absolute;
  top: 16px;
  right: 16px;
  z-index: 1;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--hairline);
}
.lightbox__close svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.5; }
.lightbox__close:hover { opacity: 0.7; }

.lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  background: var(--surface);
  border: 1px solid var(--hairline);
}
.lightbox__nav svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.5; }
.lightbox__nav:hover { opacity: 0.7; }
.lightbox__nav--prev { left: 16px; }
.lightbox__nav--next { right: 16px; }

/* Inline bespoke enquiry panel (zicstack/kj-website#18) - opened from a
   product page's "Order Bespoke" or a catalog item's "Order This Look"
   instead of navigating to /bespoke. Shares .lightbox-scrim with the
   catalog lightbox above (only one of the two is ever open at once in
   practice - CatalogGallery closes its lightbox before opening this). */
.bespoke-panel {
  position: fixed;
  inset: 0;
  z-index: 301;
  width: 90vw;
  max-width: 480px;
  height: fit-content;
  max-height: 85vh;
  overflow-y: auto;
  margin: auto;
  background: var(--surface);
  border: 1px solid var(--hairline);
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out), visibility 0.3s;
  pointer-events: none;
}
.bespoke-panel.is-open { opacity: 1; visibility: visible; transform: none; pointer-events: auto; }
.bespoke-panel__body { padding: var(--gutter); padding-top: 56px; }

/* Itemized list shown in the panel when >=1 looks were submitted together
   (zicstack/kj-website#24) - single-item submissions never render this. */
.bespoke-panel__items {
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 4px;
}
.bespoke-panel__items li {
  padding: 6px 10px;
  background: var(--bg);
  font-size: 13px;
  color: var(--muted);
}

.form__error { font-size: 13px; color: #E0685C; }
.form__success { padding: 8px 0; }

/* Floating "save your looks" bar (zicstack/kj-website#24) - hidden until
   at least one look is liked. */
.look-bar {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 250;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 16px;
  background: var(--surface);
  border: 1px solid var(--hairline);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}
.look-bar__thumbs { display: flex; }
.look-bar__thumb {
  width: 32px;
  height: 32px;
  object-fit: cover;
  border: 2px solid var(--surface);
  margin-left: -10px;
}
.look-bar__thumb:first-child { margin-left: 0; }
.look-bar__more {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  margin-left: -10px;
  background: var(--bg);
  border: 2px solid var(--surface);
  font-size: 11px;
  color: var(--muted);
}
.look-bar__count {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
}
.look-bar__clear { padding: 8px 14px; font-size: 12px; }

@media (max-width: 768px) {
  .bespoke-panel { width: auto; inset: 12px; max-width: none; max-height: none; margin: 0; }
  .look-bar { left: 12px; right: 12px; bottom: 12px; transform: none; flex-wrap: wrap; justify-content: center; }
}

/* Forms */
.form { display: grid; gap: 16px; max-width: 560px; }
.form__row { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; }

.field {
  width: 100%;
  padding: 12px 16px;
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--text);
  font: inherit;
  font-size: 14px;
}
.field::placeholder { color: var(--muted); }
.field:focus { outline: 1px solid var(--accent); outline-offset: -1px; border-color: transparent; }
textarea.field { min-height: 140px; resize: vertical; }

/* Detail list, used for showroom and garment specifics */
.facts { display: grid; gap: 0; }
.facts__row { display: flex; gap: 24px; padding: 16px 0; border-bottom: 1px solid var(--hairline); }
.facts__key { min-width: 140px; font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.facts__val { font-size: 14px; }

@media (max-width: 1024px) {
  .steps { grid-template-columns: repeat(2, 1fr); }
  .step:nth-child(2n) { border-right: 0; }
  .plate-grid { grid-template-columns: repeat(2, 1fr); }

  .bento { grid-template-columns: repeat(2, 1fr); }
  .bento__item--lg, .bento__item--md { grid-column: span 2; }
  .bento__item--sm { grid-column: span 1; }

  .lightbox { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto; max-height: 90vh; }
  .lightbox__media { min-height: 240px; }
}

@media (max-width: 768px) {
  .page-head { padding-top: calc(var(--nav-h) + 48px); }
  .tabs { padding: 64px 0 40px; }
  .tab { width: 50%; }
  .rail .card { flex: 0 0 260px; width: 260px; }
  .split { grid-template-columns: 1fr; }
  .split--flip .split__media { order: 0; }
  .split__media { min-height: 320px; }
  .split__body { padding: 48px var(--gutter); }
  .steps { grid-template-columns: 1fr; }
  .step { border-right: 0; border-bottom: 1px solid var(--hairline); }
  .plate-grid { grid-template-columns: 1fr; }
  .form__row { grid-template-columns: 1fr; }

  .bento { grid-template-columns: 1fr; grid-auto-rows: 220px; grid-auto-flow: row; }
  .bento__item--lg { grid-column: span 1; grid-row: span 2; }
  .bento__item--md, .bento__item--sm { grid-column: span 1; grid-row: span 1; }

  .lightbox { width: auto; inset: 12px; max-width: none; max-height: none; margin: 0; }
  .lightbox__nav--prev { left: 8px; }
  .lightbox__nav--next { right: 8px; }
}

/* ==========================================================================
   Cart drawer
   The reference never mounts its cart (Framer Commerce, absent on the demo),
   so there was nothing to measure. Built in this system's own vocabulary:
   zero radius, #111111 surface, #1F1F1F rules, the same type scale.
   ========================================================================== */
.cart-scrim {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(11, 11, 11, 0.6);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s;
}
body.cart-open .cart-scrim { opacity: 1; visibility: visible; }

.cart {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 201;
  display: flex;
  flex-direction: column;
  width: min(420px, 100%);
  background: var(--surface);
  border-left: 1px solid var(--divider);
  transform: translateX(100%);
  visibility: hidden;
  transition: transform 0.4s var(--ease), visibility 0.4s;
}
body.cart-open .cart { transform: none; visibility: visible; }

.cart__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--nav-h);
  padding-inline: var(--gutter);
  border-bottom: 1px solid var(--divider);
}

.cart__title { font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; }

.cart__close { display: grid; place-items: center; width: 32px; height: 32px; margin-right: -8px; }
.cart__close svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.5; }
.cart__close:hover { opacity: 0.6; }

.cart__body { flex: 1; overflow-y: auto; }

.cart__empty {
  display: grid;
  place-items: center;
  gap: 16px;
  height: 100%;
  padding: var(--gutter);
  text-align: center;
}

.cart__line {
  display: grid;
  grid-template-columns: 72px 1fr;
  gap: 16px;
  padding: var(--gutter);
  border-bottom: 1px solid var(--divider);
}

.cart__thumb { aspect-ratio: 2 / 3; overflow: hidden; background: var(--bg); }
.cart__thumb img { width: 100%; height: 100%; object-fit: cover; }

.cart__line-name { font-size: 14px; line-height: 1.4; }
.cart__line-price { margin-top: 4px; font-size: 13px; font-weight: 500; color: var(--muted); }

.cart__qty { display: flex; align-items: center; gap: 1px; margin-top: 12px; width: max-content; }

.cart__qty button {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  background: var(--bg);
  font-size: 14px;
  line-height: 1;
  transition: var(--fade);
}
.cart__qty button:hover { color: var(--accent); }

.cart__qty span {
  min-width: 32px;
  height: 28px;
  display: grid;
  place-items: center;
  background: var(--bg);
  font-size: 13px;
  font-weight: 500;
}

.cart__remove {
  margin-top: 12px;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cart__remove:hover { color: var(--text); }

.cart__foot { border-top: 1px solid var(--divider); padding: var(--gutter); }

.cart__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 16px;
}
.cart__total { font-size: 18px; font-weight: 500; }

.cart__checkout {
  width: 100%;
  height: 40px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: var(--fade);
}
.cart__checkout:hover { opacity: 0.82; }
.cart__checkout:disabled { opacity: 0.5; cursor: default; }
.cart__note { margin-top: 12px; text-align: center; }

.cart__email-label { display: block; margin-bottom: 8px; font-size: 12px; color: var(--muted); }
.cart__email { margin-bottom: 12px; }
.cart__error { margin-bottom: 12px; font-size: 13px; color: #E0685C; }

/* ==========================================================================
   Product page
   Same split logic as the category sections: imagery scrolls, the detail
   panel stays put beside it.
   ========================================================================== */
.pdp {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  margin-top: var(--nav-h);
}

.pdp__gallery { display: grid; gap: 0; }
.pdp__shot { width: 100%; aspect-ratio: 2 / 3; object-fit: cover; background: var(--surface); }

.pdp__panel { position: relative; }

.pdp__inner {
  position: sticky;
  top: var(--nav-h);
  padding: 64px var(--gutter);
}
.pdp__inner > * + * { margin-top: 16px; }

.pdp__price { font-size: 18px; font-weight: 500; }
.pdp__hook { max-width: 460px; }

.size-row { display: flex; flex-wrap: wrap; gap: 1px; margin-top: 8px; }

.size {
  min-width: 48px;
  height: 40px;
  padding-inline: 12px;
  background: var(--surface);
  font-size: 13px;
  letter-spacing: 0.04em;
  transition: var(--fade), background-color 0.3s ease, color 0.3s ease;
}
.size:hover { color: var(--accent); }
.size.is-active { background: var(--text); color: var(--on-accent); }

.pdp__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.pdp__add { min-width: 180px; }

.pdp__body { margin-top: 32px; }
.pdp__note { margin-top: 16px; }

@media (max-width: 768px) {
  .pdp { grid-template-columns: 1fr; }
  .pdp__inner { position: static; padding: 40px var(--gutter); }
}

/* ==========================================================================
   Coming soon
   A teaser, so it carries a stripped nav and footer: one conversion path
   rather than the full site's navigation.
   ========================================================================== */
.cs-hero__content { max-width: 560px; }
.cs-hero__content > * + * { margin-top: 16px; }

.countdown { display: flex; gap: 1px; margin-top: 24px; }

.countdown__unit {
  display: grid;
  place-items: center;
  gap: 4px;
  min-width: 84px;
  padding: 12px 8px;
  background: rgba(17, 17, 17, 0.85);
}

.countdown__num {
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.countdown__label {
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.waitlist {
  display: grid;
  place-items: center;
  gap: 24px;
  padding: 80px var(--gutter);
  background: var(--surface);
  text-align: center;
}

.waitlist__form { display: flex; width: min(520px, 100%); border: 1px solid var(--divider); }

.waitlist__form .field { border: 0; }
.waitlist__form .btn { flex-shrink: 0; }

.waitlist__done { color: var(--accent); }

.cs-footer {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 40px;
  flex-wrap: wrap;
  padding: 48px var(--gutter);
  background: var(--surface);
}

@media (max-width: 768px) {
  .countdown__unit { min-width: 0; flex: 1; }
  .countdown__num { font-size: 22px; }
}
