/* =========================================================================
   DUAL — Architectural Canvas
   Raw plaster field, matte carbon ink, 1px structure, zero radius.
   No shadows, no gradients as decoration, no rounded corners, no carousel.
   The grid lines do the work that shadows usually do.
   ========================================================================= */

:root {
  --plaster: #ebebe8;
  --bone: #e4e2dc;
  --carbon: #121212;
  --carbon-2: #16181a;
  --concrete: #c9c6be;
  --olive: #4e5145;
  --sage: #8a8c7e;
  --fog: #9fa1a0;
  --sand: #c9bfa9;
  --midnight: #23283a;
  --rust: #8e4a2f;
  --bordeaux: #5a2230;
  --natural: #d6cfc0;

  --ink: var(--carbon);
  --ink-60: rgba(18, 18, 18, 0.6);
  --ink-40: rgba(18, 18, 18, 0.4);
  --ink-22: rgba(18, 18, 18, 0.22);
  --ink-12: rgba(18, 18, 18, 0.12);
  --rule: 1px solid var(--ink);
  --rule-faint: 1px solid var(--ink-22);

  --paper: #ebebe8;
  --paper-deep: #e2e1dc;

  --gap-section: 160px;
  --gap-block: 56px;
  --gap-tight: 8px;
  --gap-card: 14px;

  --col: 12;
  --gutter: 24px;
  --pad-x: clamp(20px, 4.4vw, 72px);

  --font-display: "Archivo Black", "Space Grotesk", "Helvetica Neue", sans-serif;
  --font-body: "Space Grotesk", "Helvetica Neue", Arial, sans-serif;

  --mono-num: "Space Grotesk", ui-monospace, monospace;

  --texture-plaster: url('/img/texture/plaster.png');
  --texture-concrete: url('/img/texture/concrete.png');
  --texture-paper: url('/img/texture/paper.png');

  --ease: cubic-bezier(0.2, 0.9, 0.2, 1); /* hard deceleration, no bounce */
  --dur: 180ms;
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  font-weight: 400;
  letter-spacing: -0.005em;
  overflow-x: hidden;
}

/* Paper tooth. Two matched grain layers, not a single near-black one, so the
   field keeps texture after rasterisation instead of flattening to grey. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: var(--texture-plaster);
  background-size: 512px 512px;
  opacity: 0.55;
  mix-blend-mode: multiply;
}

img,
svg,
video,
canvas {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  border: 0;
  background: none;
  cursor: pointer;
}

input,
select,
textarea {
  font: inherit;
  color: inherit;
  background: transparent;
}

::selection {
  background: var(--carbon);
  color: var(--plaster);
}

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

/* ---------------------------------------------------------------- rhythm */

.shell {
  position: relative;
  z-index: 1;
}

.wrap {
  padding-inline: var(--pad-x);
  max-width: 1680px;
  margin-inline: auto;
}

.wrap-narrow {
  padding-inline: var(--pad-x);
  max-width: 1120px;
  margin-inline: auto;
}

section + section {
  margin-top: var(--gap-section);
}

@media (max-width: 900px) {
  :root {
    --gap-section: 88px;
  }
}

.rule-top {
  border-top: var(--rule);
}

.rule-bottom {
  border-bottom: var(--rule);
}

/* ------------------------------------------------------------- typography */

.eyebrow {
  font-size: 11px;
  line-height: 1.2;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-60);
}

.eyebrow--ink {
  color: var(--ink);
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.86;
  margin: 0;
}

.display {
  font-family: var(--font-display);
  text-transform: uppercase;
  line-height: 0.82;
  letter-spacing: -0.03em;
  font-size: clamp(44px, 11.5vw, 190px);
  margin: 0;
}

.h-xl {
  font-size: clamp(34px, 5.6vw, 84px);
}

.h-lg {
  font-size: clamp(26px, 3.6vw, 52px);
}

.h-md {
  font-size: clamp(20px, 2.2vw, 30px);
  letter-spacing: -0.015em;
}

.h-sm {
  font-size: 15px;
  letter-spacing: 0.06em;
}

.lede {
  font-size: clamp(17px, 1.5vw, 22px);
  line-height: 1.45;
  max-width: 46ch;
  font-weight: 500;
}

p {
  margin: 0 0 1em;
  max-width: 68ch;
}

p:last-child {
  margin-bottom: 0;
}

.num {
  font-family: var(--mono-num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: -0.01em;
}

.num--tight {
  letter-spacing: -0.03em;
}

.num--big {
  font-size: clamp(22px, 2.4vw, 34px);
  font-weight: 600;
}

.mono {
  font-family: var(--mono-num);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--carbon);
  color: var(--plaster);
  padding: 12px 18px;
}

.skip-link:focus {
  left: 0;
}

/* ------------------------------------------------------------- 1px grids */

.grid {
  display: grid;
  grid-template-columns: repeat(var(--col), minmax(0, 1fr));
  gap: var(--gutter);
}

.grid--ruled {
  gap: 0;
  border-top: var(--rule);
  border-left: var(--rule);
}

.grid--ruled > * {
  border-right: var(--rule);
  border-bottom: var(--rule);
  padding: 16px;
  margin-left: -1px;
}

.stack > * + * {
  margin-top: var(--gap-block);
}

.stack-tight > * + * {
  margin-top: var(--gap-card);
}

.split-60-40 {
  display: grid;
  grid-template-columns: 6fr 4fr;
  gap: var(--gutter);
}

.split-70-30 {
  display: grid;
  grid-template-columns: 7fr 3fr;
  gap: var(--gutter);
}

.split-40-60 {
  display: grid;
  grid-template-columns: 4fr 6fr;
  gap: var(--gutter);
}

@media (max-width: 980px) {
  .split-60-40,
  .split-70-30,
  .split-40-60 {
    grid-template-columns: 1fr;
    gap: 40px;
  }
}

.row {
  display: flex;
  align-items: center;
  gap: 14px;
}

.row--between {
  justify-content: space-between;
}

.row--wrap {
  flex-wrap: wrap;
}

.baseline {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}

/* ------------------------------------------------------------------ chrome */

.masthead {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--paper);
  border-bottom: var(--rule);
}

.masthead__inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 24px;
  padding-block: 14px;
}

.masthead__brand {
  display: block;
  height: 20px;
  width: auto;
}

.masthead__brand img {
  height: 20px;
  width: auto;
}

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

.nav a {
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur) var(--ease);
  /* Labels are single-line contracts; a flex-shrunk anchor would otherwise
     break "HOODIES & CREWNECK" across two lines on narrower viewports. */
  white-space: nowrap;
}

.nav a:hover,
.nav a[aria-current="page"] {
  border-color: var(--ink);
}

.nav--primary {
  /* The masthead grid gives the nav the middle 1fr column; without this it
     hugs the brand. Centered between the wordmark and the cart cluster. */
  justify-content: center;
}

@media (max-width: 860px) {
  .nav--primary {
    display: none;
  }
}

@media (min-width: 861px) {
  /* `auto 1fr auto` centers the nav in the *leftover* space, which sits off
     true center by (cart − brand)/2. Symmetric 1fr side tracks make the middle
     column the page's real center, and keep it there when the cart strip
     re-renders wider or narrower via AJAX. */
  .masthead__inner {
    grid-template-columns: 1fr auto 1fr;
  }

  .masthead__brand {
    justify-self: start;
  }

  #cart-strip {
    justify-self: end;
  }
}

.cart-count {
  display: inline-block;
  min-width: 20px;
  text-align: center;
  border: var(--rule);
  padding: 1px 5px;
  font-size: 11px;
  font-family: var(--mono-num);
}

/* The ticker strip: pure information, no decoration. */
.ticker {
  border-bottom: var(--rule);
  background: var(--carbon);
  color: var(--plaster);
  overflow: hidden;
}

.ticker__track {
  display: flex;
  padding-block: 7px;
  white-space: nowrap;
  width: max-content;
  /* ~43 px/s, the pace the strip had when it carried seven lines. */
  animation: ticker 45s linear infinite;
}

.ticker span {
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  /* Per-item trailing space, not a track gap: with a duplicated list, `gap` leaves
     an odd number of gaps (n copies × k items + 1 seam), so the loop falls half a
     gap short of the true period and every wrap snaps the spacing. A margin on each
     span makes each copy exactly one period wide, so the loop is seamless at any
     item count. The gap is deliberately huge: with only three short lines, the one
     period must still exceed a 1920 px viewport, or the same line shows twice on
     screen at once. Airiness is cheaper than duplication. */
  margin-inline-end: 330px;
}

@keyframes ticker {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    /* Track holds exactly three copies; -100%/3 advances one full period. */
    transform: translate3d(calc(-100% / 3), 0, 0);
  }
}

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

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

.footer {
  margin-top: var(--gap-section);
  border-top: var(--rule);
  padding-block: 48px 32px;
}

.footer__grid {
  display: grid;
  grid-template-columns: repeat(var(--col), minmax(0, 1fr));
  gap: 32px;
}

.footer__col {
  grid-column: span 3;
}

.footer__col--wide {
  grid-column: span 6;
}

@media (max-width: 900px) {
  .footer__col,
  .footer__col--wide {
    grid-column: span 6;
  }
}

.footer ul {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.footer a:hover {
  border-bottom: var(--rule);
}

.footer__legal {
  margin-top: 40px;
  padding-top: 14px;
  border-top: var(--rule-faint);
  display: flex;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  color: var(--ink-60);
}

/* ------------------------------------------------------------------ buttons */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  border: var(--rule);
  background: transparent;
  color: var(--ink);
  padding: 13px 20px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 0;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
    border-color var(--dur) var(--ease);
  /* instant invert, no lift */
}

.btn__arrow {
  display: inline-block;
  transition: transform var(--dur) var(--ease);
}

.btn:hover,
.btn:focus-visible {
  background: var(--carbon);
  color: var(--plaster);
  border-color: var(--carbon);
}

.btn:hover .btn__arrow,
.btn:focus-visible .btn__arrow {
  transform: translateX(5px);
}

.btn--solid {
  background: var(--carbon);
  color: var(--plaster);
}

.btn--solid:hover,
.btn--solid:focus-visible {
  background: var(--plaster);
  color: var(--carbon);
}

.btn--full {
  width: 100%;
  justify-content: space-between;
}

.btn--ghost {
  border-color: var(--ink-22);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.4;
  pointer-events: none;
}

.btn--sm {
  padding: 8px 12px;
  font-size: 11px;
  letter-spacing: 0.1em;
}

.link-underline {
  border-bottom: var(--rule);
  padding-bottom: 2px;
}

.link-underline:hover {
  background: var(--carbon);
  color: var(--plaster);
  border-color: var(--carbon);
}

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

.field {
  display: grid;
  gap: 6px;
  margin-bottom: 18px;
}

.field__label {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-60);
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="number"],
.field input[type="password"],
.field input[type="search"],
.field input[type="date"],
.field select,
.field textarea {
  width: 100%;
  border: 1px solid var(--ink);
  border-radius: 2px; /* radius is allowed only on form fields and the loupe lens */
  padding: 12px 12px;
  background: rgba(255, 255, 255, 0.42);
  transition: box-shadow var(--dur) var(--ease);
}

.field textarea {
  min-height: 96px;
  resize: vertical;
}

.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%),
    linear-gradient(135deg, var(--ink) 50%, transparent 50%);
  background-position: calc(100% - 16px) 51%, calc(100% - 11px) 51%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 34px;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  box-shadow: inset 0 -2px 0 var(--carbon);
}

.field__hint {
  font-size: 12px;
  color: var(--ink-60);
}

.field__error {
  font-size: 12px;
  color: var(--rust);
  font-weight: 500;
}

.field--error input,
.field--error select {
  border-color: var(--rust);
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 16px;
}

.field-row--3 {
  grid-template-columns: 1fr 1fr 1fr;
}

@media (max-width: 640px) {
  .field-row,
  .field-row--3 {
    grid-template-columns: 1fr;
  }
}

/* switch-style radio cards (size, courier, payment) */
.choices {
  display: grid;
  gap: 0;
  border: var(--rule);
}

.choices--inline {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border: 0;
}

.choice {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px;
  padding: 14px 16px;
  border-top: var(--rule);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.choice__price {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: start;
  text-align: right;
  font-family: var(--mono-num);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding-left: 16px;
}

.choice:first-child {
  border-top: 0;
}

.choice input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.choice:hover {
  background: var(--ink-12);
}

.choice:has(input:checked) {
  background: var(--carbon);
  color: var(--plaster);
}

.choice:has(input:focus-visible) {
  outline: 2px solid var(--carbon);
  outline-offset: -4px;
}

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

.choice__meta {
  font-size: 11px;
  opacity: 0.72;
  letter-spacing: 0.04em;
}

.choice--pad {
  padding: 10px 12px;
  border: var(--rule);
  border-top-width: 0;
  border-left-width: 0;
  text-align: center;
  min-width: 62px;
  font-family: var(--mono-num);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.sizes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(62px, 1fr));
  border-left: var(--rule);
  border-top: var(--rule);
}

.size--out {
  color: var(--ink-40);
  text-decoration: line-through;
  pointer-events: none;
}

/* ------------------------------------------------------------------ tables */

.spec {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.spec caption {
  text-align: left;
  padding-bottom: 10px;
}

.spec th,
.spec td {
  border-top: var(--rule-faint);
  padding: 11px 0;
  text-align: left;
  vertical-align: top;
}

.spec tr:last-child td,
.spec tr:last-child th {
  border-bottom: var(--rule);
}

.spec th {
  width: 42%;
  font-weight: 500;
  color: var(--ink-60);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.spec td.num {
  font-weight: 600;
}

.table-lines {
  width: 100%;
  border-collapse: collapse;
}

.table-lines th {
  text-align: left;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-60);
  padding: 10px 0;
  border-bottom: var(--rule);
  font-weight: 600;
}

.table-lines td {
  padding: 16px 0;
  border-bottom: var(--rule-faint);
  vertical-align: top;
}

/* ------------------------------------------------------------- art frames */

.frame {
  position: relative;
  border: var(--rule);
  background: var(--bone);
  overflow: hidden;
}

.frame--bare {
  border: 0;
  background: none;
}

.frame__img {
  width: 100%;
  height: auto;
  display: block;
}

.frame__tag {
  position: absolute;
  top: 0;
  left: 0;
  background: var(--paper);
  border-right: var(--rule);
  border-bottom: var(--rule);
  padding: 5px 9px;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
}

.swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: var(--rule);
  vertical-align: -1px;
  margin-right: 6px;
}

/* catalogue: staggered editorial grid, never a 4-up equal row */
.catalogue {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: 72px;
  align-items: start;
}

.card {
  grid-column: span 4;
  display: block;
}

.card--offset {
  margin-top: 108px;
}

.card--wide {
  grid-column: span 6;
}

.card--tall {
  grid-column: span 5;
}

@media (max-width: 1100px) {
  .card,
  .card--wide,
  .card--tall {
    grid-column: span 6;
  }

  .card--offset {
    margin-top: 48px;
  }
}

@media (max-width: 700px) {
  .catalogue {
    row-gap: 48px;
  }

  .card,
  .card--wide,
  .card--tall {
    grid-column: span 12;
    margin-top: 0;
  }
}

.card__media {
  position: relative;
  display: block;
  border: var(--rule);
  background: var(--bone);
  overflow: hidden;
}

.card__media img {
  width: 100%;
  height: auto;
}

.card__rail {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 0;
  border-bottom: var(--rule-faint);
}

.card__index {
  font-size: 10px;
  letter-spacing: 0.16em;
  font-family: var(--mono-num);
  background: var(--paper);
  padding: 2px 6px;
  border: var(--rule-faint);
}

.card__state {
  background: var(--carbon);
  color: var(--plaster);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 4px 8px;
}

.card__body {
  padding-top: 12px;
}

.card__name {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 17px;
  line-height: 1.05;
  letter-spacing: -0.01em;
  margin: 0 0 4px;
}

.card__specs {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-60);
}

.card__foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: var(--rule-faint);
}

.price {
  font-family: var(--mono-num);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.price--was {
  color: var(--ink-40);
  text-decoration: line-through;
  font-weight: 400;
  margin-right: 8px;
}

/* Money::html() emits the symbol and the digits as adjacent spans; the gap is
   typography, not a stray space character, so it survives minification. */
.price__cur {
  /* the gap comes from a real space character in the markup (see Money::html), so
     margin-right here would double it up */
  letter-spacing: 0.08em;
  font-size: 0.82em;
  opacity: 0.72;
  white-space: nowrap;
}

/* filter rail */
.rail {
  border-top: var(--rule);
}

.rail__group {
  border-bottom: var(--rule);
  padding-block: 16px;
}

.rail__group summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.rail__group summary::-webkit-details-marker {
  display: none;
}

.rail__group[open] summary .rail__plus {
  transform: rotate(45deg);
}

.rail__plus {
  transition: transform var(--dur) var(--ease);
  font-size: 14px;
  line-height: 1;
}

.chipset {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
}

.chip {
  border: var(--rule);
  padding: 5px 9px;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  background: transparent;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.chip:hover {
  background: var(--ink-12);
}

.chip[aria-pressed="true"],
.chip--on {
  background: var(--carbon);
  color: var(--plaster);
}

.chip--clear {
  border-color: var(--ink-22);
  color: var(--ink-60);
}

.pager {
  display: flex;
  gap: 4px;
  align-items: center;
  margin-top: 64px;
  padding-top: 16px;
  border-top: var(--rule);
}

.pager a,
.pager span {
  border: var(--rule-faint);
  padding: 7px 12px;
  font-size: 12px;
  font-family: var(--mono-num);
}

.pager [aria-current="page"] {
  background: var(--carbon);
  color: var(--plaster);
  border-color: var(--carbon);
}

/* ------------------------------------------------- product detail page */

.pdp {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: var(--gutter);
  align-items: start;
}

@media (max-width: 1080px) {
  .pdp {
    grid-template-columns: 1fr;
  }
}

.pdp__gallery {
  display: grid;
  gap: 0;
  border: var(--rule);
  position: sticky;
  top: 84px;
  background: var(--bone);
}

.pdp__stage {
  position: relative;
}

.pdp__stage img {
  width: 100%;
}

.pdp__thumbs {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  border-top: var(--rule);
}

.pdp__thumb {
  border-left: var(--rule);
  padding: 0;
  background: var(--bone);
  position: relative;
}

.pdp__thumb:first-child {
  border-left: 0;
}

.pdp__thumb img {
  width: 100%;
  opacity: 0.75;
  transition: opacity var(--dur) var(--ease);
}

.pdp__thumb:hover img,
.pdp__thumb[aria-current="true"] img {
  opacity: 1;
}

.pdp__thumb[aria-current="true"]::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 3px;
  background: var(--carbon);
}

.pdp__buy {
  border-top: var(--rule);
  padding-top: 22px;
}

.pdp__aside {
  display: grid;
  gap: 26px;
}

.feature-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0;
  border-top: var(--rule);
}

.feature-list li {
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: 12px;
  align-items: start;
  padding: 12px 0;
  border-bottom: var(--rule-faint);
  font-size: 13px;
}

.feature-list svg {
  width: 20px;
  height: 20px;
  stroke: var(--ink);
  stroke-width: 1;
  fill: none;
}

.tabs {
  border-top: var(--rule);
}

.tabs__list {
  display: flex;
  gap: 0;
  border-bottom: var(--rule);
  flex-wrap: wrap;
}

.tabs__tab {
  padding: 14px 18px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  border-right: var(--rule);
  border-bottom: 2px solid transparent;
  background: transparent;
}

.tabs__tab[aria-selected="true"] {
  background: var(--carbon);
  color: var(--plaster);
}

.tabs__panel {
  padding: 26px 0;
}

.tabs__panel[hidden] {
  display: none;
}

/* --------------------------------------------- material inspect loupe */

.loupe {
  position: fixed;
  top: 0;
  left: 0;
  width: 220px;
  height: 220px;
  z-index: 70;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur) linear;
  /* transform is written per-frame by dual.js — never transition it */
}

.loupe[data-on="true"] {
  opacity: 1;
}

.loupe__ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--carbon);
  background: var(--bone);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(235, 235, 232, 0.7);
}

.loupe__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transform-origin: center center;
}

.loupe__hair {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: linear-gradient(to right, transparent calc(50% - 0.5px), var(--ink-40) calc(50% - 0.5px), var(--ink-40) calc(50% + 0.5px), transparent calc(50% + 0.5px)),
    linear-gradient(to bottom, transparent calc(50% - 0.5px), var(--ink-40) calc(50% - 0.5px), var(--ink-40) calc(50% + 0.5px), transparent calc(50% + 0.5px));
}

.loupe__label {
  position: absolute;
  bottom: -26px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 600;
  background: var(--paper);
  border: var(--rule-faint);
  padding: 2px 7px;
}

.loupe__scale {
  position: absolute;
  top: -22px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: flex-end;
  gap: 3px;
  font-size: 9px;
  letter-spacing: 0.1em;
  font-family: var(--mono-num);
}

.loupe__scale i {
  display: block;
  width: 26px;
  height: 5px;
  border-left: var(--rule);
  border-right: var(--rule);
  position: relative;
}

.loupe__scale i::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  width: 1px;
  height: 3px;
  background: var(--ink);
}

/* ------------------------------------------------- kinetic watermark */

.watermark {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

.watermark__word {
  position: absolute;
  left: 50%;
  top: 50%;
  display: flex;
  font-family: var(--font-display);
  font-size: clamp(180px, 42vw, 620px);
  line-height: 0.8;
  color: var(--carbon);
  opacity: 0.05;
  will-change: transform;
}

.watermark__word span {
  display: block;
  will-change: transform;
}

/* --------------------------------------------------------- qty stepper */

.stepper {
  display: inline-flex;
  border: var(--rule);
  align-items: stretch;
}

.stepper button {
  width: 38px;
  border-right: var(--rule);
  font-size: 15px;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.stepper button:last-child {
  border-right: 0;
  border-left: var(--rule);
}

.stepper button:hover {
  background: var(--carbon);
  color: var(--plaster);
}

.stepper input {
  width: 52px;
  text-align: center;
  border: 0;
  font-family: var(--mono-num);
  font-weight: 600;
  background: transparent;
}

/* --------------------------------------------------------- notices */

.notice {
  border: var(--rule);
  border-left-width: 4px;
  padding: 12px 16px;
  font-size: 13px;
  margin-bottom: 22px;
  background: rgba(255, 255, 255, 0.4);
}

.notice--ok {
  border-left-color: var(--olive);
}

.notice--err {
  border-left-color: var(--rust);
}

.notice--info {
  border-left-color: var(--midnight);
}

.notice ul {
  margin: 6px 0 0;
  padding-left: 18px;
}

/* --------------------------------------------------------- steps rail */

.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: var(--rule);
  margin-bottom: 40px;
}

.steps__step {
  padding: 12px 14px;
  border-left: var(--rule);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-40);
  display: flex;
  gap: 8px;
  align-items: baseline;
}

.steps__step:first-child {
  border-left: 0;
}

.steps__step[data-state="done"] {
  color: var(--ink);
}

.steps__step[data-state="current"] {
  background: var(--carbon);
  color: var(--plaster);
}

@media (max-width: 700px) {
  .steps {
    grid-template-columns: repeat(2, 1fr);
  }

  .steps__step:nth-child(3) {
    border-left: 0;
  }
}

/* --------------------------------------------------------- order summary */

.summary {
  border: var(--rule);
  padding: 0;
  background: rgba(255, 255, 255, 0.35);
}

.summary__row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 16px;
  border-bottom: var(--rule-faint);
  font-size: 13px;
}

.summary__row:last-child {
  border-bottom: 0;
}

.summary__row--total {
  border-top: var(--rule);
  font-size: 17px;
  font-weight: 600;
}

.summary__head {
  padding: 14px 16px;
  border-bottom: var(--rule);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

/* a QRIS payload is data, so draw it as data: no image library needed */
.qr {
  display: grid;
  gap: 10px;
  justify-items: center;
  border: var(--rule);
  padding: 18px;
  background: #fff;
  width: max-content;
}

.qr canvas {
  width: 220px;
  height: 220px;
  image-rendering: pixelated;
}

.copy-box {
  border: var(--rule);
  padding: 12px 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  background: var(--paper);
  font-family: var(--mono-num);
  letter-spacing: 0.06em;
}

/* --------------------------------------------------------- utilities */

.u-mt-0 {
  margin-top: 0 !important;
}

.u-mt-s {
  margin-top: 12px;
}

.u-mt-m {
  margin-top: 24px;
}

.u-mt-l {
  margin-top: 48px;
}

.u-mt-xl {
  margin-top: 88px;
}

.u-mb-s {
  margin-bottom: 12px;
}

.u-mb-m {
  margin-bottom: 24px;
}

.u-mb-l {
  margin-bottom: 48px;
}

.u-ink {
  color: var(--ink-60);
}

.u-hide-sm {
  display: none;
}

@media (min-width: 900px) {
  .u-hide-sm {
    display: revert;
  }

  .u-show-sm {
    display: none;
  }
}

.u-inverse {
  background: var(--carbon);
  color: var(--plaster);
}

.u-inverse .eyebrow,
.u-inverse .u-ink {
  color: rgba(235, 235, 232, 0.62);
}

.u-caps {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 11px;
  font-weight: 600;
}

.u-rule-b {
  border-bottom: var(--rule);
}

.u-rule-t {
  border-top: var(--rule);
}

.u-max-60 {
  max-width: 60ch;
}

.u-num-right {
  text-align: right;
  font-family: var(--mono-num);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------- storefront surfaces */

/* Mobile nav. A native <details> keeps this working with zero JavaScript and reads
   like the rest of the system: a ruled drawer, no chrome. */
.nav--mobile {
  border: 0;
}

.nav--mobile > summary {
  list-style: none;
  cursor: pointer;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  padding-bottom: 3px;
  border-bottom: 1px solid transparent;
}

.nav--mobile > summary::-webkit-details-marker {
  display: none;
}

.nav--mobile[open] > summary {
  border-color: var(--ink);
}

.nav--mobile__panel {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: var(--paper);
  border-bottom: var(--rule);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.nav--mobile__panel a {
  padding: 16px var(--pad-x);
  border-top: var(--rule-faint);
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
}

.nav--mobile__panel a:first-child {
  border-top: 0;
}

@media (min-width: 861px) {
  .nav--mobile {
    display: none;
  }
}

/* Bag / checkout line rows: image left, spec middle, numbers right, 1px between. */
.bag-line {
  display: grid;
  grid-template-columns: 88px 1fr auto;
  gap: 18px;
  padding: 18px 0;
  border-bottom: var(--rule-faint);
  align-items: start;
}

.bag-line:first-child {
  padding-top: 0;
}

.bag-line__media {
  border: var(--rule);
  background: var(--bone);
  display: block;
}

.bag-line__media img {
  display: block;
  width: 100%;
  height: auto;
}

.bag-line__name {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: 15px;
  line-height: 1.05;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
}

.bag-line__meta {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-60);
  display: grid;
  gap: 3px;
}

.bag-line__right {
  display: grid;
  gap: 10px;
  justify-items: end;
  text-align: right;
}

@media (max-width: 700px) {
  .bag-line {
    grid-template-columns: 64px 1fr;
  }

  .bag-line__right {
    grid-column: 1 / -1;
    justify-items: start;
    text-align: left;
  }
}

/* Front page opening: 60/40 split, plate bleeding into the rule grid. */
.hero {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: var(--gutter);
  align-items: end;
  padding-top: clamp(48px, 7vw, 96px);
}

.hero__title {
  font-size: clamp(56px, 12vw, 210px);
}

.hero__plate {
  border: var(--rule);
  background: var(--bone);
  position: relative;
}

.hero__plate img {
  display: block;
  width: 100%;
}

.hero__index {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: var(--rule);
  border-left: var(--rule);
  margin-top: var(--gap-block);
}

.hero__index > div {
  border-right: var(--rule);
  border-bottom: var(--rule);
  padding: 14px 16px;
}

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    align-items: start;
  }

  .hero__index {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Full-bleed inverted band for the material index and shipping explainer. */
.band {
  background: var(--carbon);
  color: var(--plaster);
  padding-block: clamp(48px, 6vw, 88px);
  margin-block: var(--gap-section) 0;
  border-block: var(--rule);
}

.band .eyebrow {
  color: rgba(235, 235, 232, 0.62);
}

.band .lede {
  color: var(--plaster);
}

.band--bone {
  background: var(--bone);
  color: var(--ink);
}

.band--bone .eyebrow {
  color: var(--ink-60);
}

/* Material index rows: macro thumbnail, weave data, count. */
.weave-row {
  display: grid;
  grid-template-columns: 120px 1fr auto;
  gap: 20px;
  align-items: center;
  padding: 16px 0;
  border-top: 1px solid rgba(235, 235, 232, 0.22);
}

.weave-row:last-child {
  border-bottom: 1px solid rgba(235, 235, 232, 0.22);
}

.weave-row img {
  width: 120px;
  height: 88px;
  object-fit: cover;
  display: block;
  border: 1px solid var(--plaster);
}

.weave-row__gsm {
  font-family: var(--mono-num);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

/* Rate-card and size-chart matrices: ruled, dense, tabular. */
.matrix {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.matrix th,
.matrix td {
  border: var(--rule-faint);
  padding: 10px 12px;
  text-align: left;
  vertical-align: top;
}

.matrix thead th {
  border-color: var(--ink);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  background: var(--bone);
  font-weight: 600;
}

.matrix td.num,
.matrix th.num {
  font-family: var(--mono-num);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.matrix tbody tr:hover {
  background: rgba(255, 255, 255, 0.5);
}

.matrix__off {
  color: var(--ink-40);
}

/* Small status tags: sold out, new, pickup, cod. */
.tag {
  display: inline-block;
  border: var(--rule);
  padding: 2px 7px;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 600;
  line-height: 1.5;
}

.tag--solid {
  background: var(--carbon);
  color: var(--plaster);
  border-color: var(--carbon);
}

.tag--olive {
  border-color: var(--olive);
  color: var(--olive);
}

.tag--rust {
  border-color: var(--rust);
  color: var(--rust);
}

.tag--mute {
  border-color: var(--ink-22);
  color: var(--ink-60);
}

/* Payment instrument blocks on the receipt. */
.receipt-row {
  display: grid;
  grid-template-columns: minmax(120px, 34%) 1fr;
  gap: 16px;
  padding: 10px 0;
  border-bottom: var(--rule-faint);
  font-size: 13px;
}

.receipt-row dt {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-60);
}

.receipt-row dd {
  margin: 0;
  font-family: var(--mono-num);
  word-break: break-word;
}

.empty {
  border: var(--rule);
  padding: clamp(28px, 5vw, 64px);
  text-align: center;
  background: var(--bone);
}

.divider-label {
  display: flex;
  align-items: center;
  gap: 16px;
  color: var(--ink-60);
}

.divider-label::before,
.divider-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--ink-22);
}

/* ------------------------------------------------------ JS-driven states
   dual.js only ever toggles attributes; every visual response lives here so the
   markup stays declarative and the behaviour degrades to plain HTML without it. */

[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity 420ms var(--ease), transform 420ms var(--ease);
}

[data-reveal][data-revealed="true"] {
  opacity: 1;
  transform: none;
}

.loupe__img {
  transition: opacity var(--dur) linear;
}

img[data-fade="true"] {
  animation: dual-plate 220ms var(--ease);
}

@keyframes dual-plate {
  from { opacity: 0.35; }
  to { opacity: 1; }
}

.notice[data-out="true"] {
  opacity: 0;
  transition: opacity 380ms linear;
}

[data-cart-count][data-bumped="true"] {
  background: var(--carbon);
  color: var(--plaster);
  transition: background 0ms, color 0ms;
}

.btn[data-busy="true"],
button[data-busy="true"] {
  opacity: 0.45;
  pointer-events: none;
}

[data-expedition][data-busy="true"] .choices {
  opacity: 0.5;
}

[data-expedition] {
  position: relative;
}

[data-expedition][data-busy="true"]::after {
  content: "HITUNG ULANG ONGKIR";
  position: absolute;
  top: -10px;
  right: 0;
  font-family: var(--mono-num);
  font-size: 9px;
  letter-spacing: 0.18em;
  background: var(--carbon);
  color: var(--plaster);
  padding: 2px 7px;
}

.copy-box button[data-on="true"] {
  background: var(--olive);
  color: var(--plaster);
  border-color: var(--olive);
}

.chip {
  cursor: pointer;
  user-select: none;
}

button.chip {
  appearance: none;
  background: transparent;
  border: var(--rule-faint);
  color: var(--ink);
  font: inherit;
}

.size--out {
  text-decoration: line-through;
  opacity: 0.4;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--carbon);
  color: var(--plaster);
  padding: 10px 16px;
  font-family: var(--mono-num);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.skip-link:focus {
  left: 0;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }

  img[data-fade="true"] {
    animation: none;
  }
}

@media print {
  .ticker,
  .nav--mobile {
    display: none !important;
  }

  .masthead,
  .footer,
  .watermark,
  .loupe,
  .no-print {
    display: none !important;
  }

  body {
    background: #fff;
  }
}
