/* CAVA page-level layout.
   components.css is the visual language (buttons, cards, media, forms); this
   file is composition only - how each page arranges those components. Every
   colour, radius, shadow and space below is still a token from tokens.css.

   Two conventions carried through every section:
   - Text clusters (heading + lede + cta) are laid out with `display:grid` and
     `gap`, never margins on the typographic elements themselves - one rhythm
     knob per section instead of collapsing margins to reason about.
   - Any grid whose children are a button or a link gets `justify-items:start`
     (or `center`, when the section is deliberately centred). Grid's default
     stretch would otherwise force an inline-flex `.btn` - or a plain `.link`,
     blockified once it becomes a grid item - to the full column width, which
     breaks the CTA's natural size and, for `.link`, drags its hover-underline
     out past the words it belongs to.
   ------------------------------------------------------------------------- */

/* Shared section-intro heading, reused wherever a section opens with a plain
   h2 (featured grid, feature graphic, closing band). Sits outside any single
   section on purpose - later pages may reuse it rather than reinvent it. */
.section-heading {
  font-size: var(--step-5);
  max-width: 34ch;
}

/* ---------- 1. Hero -------------------------------------------------------- */

/* One field, not two objects on a page. The band is --oat, which components.css
   establishes as *exactly* the studio background of the photography - sampled
   back out of hero/1 it runs #E9E4D8 to #F5F2EA around #EDEAE0 - so the photo has
   no visible edge against the field it sits in. That is what carries the
   composition: no radius, no shadow, no border anywhere in this section. The
   photo bleeds off the top, right and bottom of the band, leaving one interior
   boundary (its left) at exactly the tone where the two already match, and the
   women read as standing in the page rather than inside a pasted rectangle.
   Everything here is full-bleed, so .section's padding-block is zeroed and the
   breathing room lives on the copy column instead. */
.home-hero {
  padding-block: 0;
  background: var(--oat);
}

.home-hero__grid {
  display: grid;
  gap: 0;
}

.home-hero__media,
.home-hero__panel {
  min-width: 0;   /* grid items default to min-width:auto */
}

/* Photo above copy on narrow screens - it is the hook - while the DOM keeps the
   h1 first. Explicit rows rather than `order`, so the visual order the rest of
   this block depends on is stated in one place. */
.home-hero__media { grid-row: 1; }
.home-hero__panel { grid-row: 2; }

/* Overrides .media--hero's 3/2. A 4/3 box takes its cover crop off the sides
   (the box is relatively taller, so the image scales to fill the height), and
   at 4/3 that is 11% of the frame width - the outermost figures keep their
   hands and arms. 3/2 stays below, where a full-width band is short enough to
   read as a letterbox strip rather than a hero. */
.home-hero__media { --ratio: 4 / 3; }

/* The crop above is horizontal at every width up to the point the band goes
   wider than 3/2, so the y term only starts mattering on very wide viewports -
   where it drops the empty studio ceiling instead of the feet. */
.home-hero__media .media__img { object-position: 50% 58%; }

.home-hero__panel {
  display: grid;
  gap: var(--space-5);
  align-content: center;
  justify-items: start;
  padding: var(--space-8) var(--space-5) var(--space-9);
}

/* Tracked micro-label at --step--2, per the sitewide convention, with a short
   rule leading into it - the one place burgundy appears above the fold besides
   the CTA. */
.home-hero__eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--burg-soft);
  letter-spacing: .22em;
}
.home-hero__eyebrow::before {
  content: "";
  flex: none;
  width: var(--space-7);
  height: 1px;
  background: var(--burg-soft);
}

/* Not --step-7: its 52px floor sets this headline in three lines at 390px and
   crowds a 342px copy column at the 900px breakpoint. This ramp is flatter -
   44px at 390, ~54px at 900, 72px at 1440 and up - so it holds two lines from
   the smallest phone to the widest desktop. Bodoni's sidebearings open up at
   display sizes; -.02em closes them back to the h1 rhythm. */
.home-hero__title {
  font-size: clamp(2.75rem, 1.9rem + 2.6vw, 4.5rem);
  letter-spacing: -.02em;
  text-wrap: balance;
}

.home-hero__lede { max-width: 46ch; }

.home-hero__cta { margin-block-start: var(--space-2); }

@media (min-width: 900px) {
  /* Copy left, photo right and bleeding off it. The copy track is capped at
     34rem so the measure stays readable however wide the viewport goes, and the
     start padding lands the text on the container's left edge - i.e. flush with
     the wordmark in the header directly above it - by resolving the container
     inset from the grid's own containing block. Percentages here are the
     section's width, which excludes the scrollbar `scrollbar-gutter: stable`
     reserves; 100vw would not, and would push the copy half a gutter off the
     header. Below the container width the max() falls back to a plain gutter. */
  .home-hero__grid {
    grid-template-columns: minmax(0, clamp(20rem, 38vw, 34rem)) minmax(0, 1fr);
    align-items: stretch;
    column-gap: clamp(2rem, 4vw, 4rem);
    min-height: clamp(30rem, 38vw, 42rem);
    padding-inline-start: max(
      var(--space-5),
      calc((100% - var(--container)) / 2 + var(--space-5))
    );
  }

  .home-hero__panel {
    grid-column: 1;
    grid-row: 1;
    padding: var(--space-9) 0;
  }

  /* aspect-ratio must go, not just change: the row is already given a definite
     height by min-height + stretch, and a ratio left in play would resolve the
     figure's width from that height instead of letting it fill its track. */
  .home-hero__media {
    grid-column: 2;
    grid-row: 1;
    aspect-ratio: auto;
  }
}

@media (min-width: 620px) and (max-width: 899px) {
  .home-hero__media { --ratio: 3 / 2; }
}

/* ---------- 2. Value props -------------------------------------------------- */

.home-value-props__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-6);
  text-align: center;
}

/* Hairlines, not boxes: a divider between items reads as considered structure
   without wrapping each phrase in a bordered rectangle. */
.home-value-props__item {
  padding-inline: var(--space-5);
  border-left: 1px solid var(--line);
}
.home-value-props__item:first-child {
  border-left: 0;
}

@media (max-width: 899px) {
  .home-value-props__grid { grid-template-columns: repeat(2, 1fr); }
  .home-value-props__item { border-left: 0; }
  .home-value-props__item:nth-child(2n) { border-left: 1px solid var(--line); }
}

@media (max-width: 619px) {
  .home-value-props__grid { grid-template-columns: 1fr; gap: var(--space-5); }
  .home-value-props__item { border-left: 0; padding-inline: 0; }
}

/* ---------- 3. Featured sets ------------------------------------------------ */

.home-featured__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-5);
  margin-bottom: var(--space-8);
}

/* Explicit 4/2/1, not .product-grid's bare auto-fill. The previous rule here
   was 3-up, which stranded the fourth featured card alone on a second row --
   in a curated "Izdvojeno" showcase an orphan reads as a mistake, not a
   choice. 4-up seats all four featured products in one deliberate row, so
   there is nothing left over and no centering hack is needed (a stray
   nth-child rule here would actively misplace a card into the wrong column
   the moment this stopped being a 3-column grid, so it was removed with this
   change rather than left inert). Still page-scoped: this overrides only
   .home-featured__grid's column count, never .product-grid itself, so other
   pages that render a plain product-grid (e.g. the collection page) are
   unaffected. */
.home-featured__grid {
  grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 899px) {
  .home-featured__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 619px) {
  .home-featured__grid { grid-template-columns: 1fr; }
}

/* ---------- 4. Editorial band ----------------------------------------------- */

.home-editorial {
  background: var(--burgundy);
  color: var(--cream);
}
/* Same fix as the footer: the sitewide focus ring is --burgundy, invisible on
   a --burgundy field. */
.home-editorial :focus-visible {
  outline-color: var(--rose);
}

.home-editorial__inner {
  display: grid;
  justify-items: center;
  gap: var(--space-6);
  max-width: 46ch;
  margin-inline: auto;
  text-align: center;
}

.home-editorial__quote {
  font-family: var(--font-display);
  font-size: var(--step-5);
  line-height: 1.3;
}

/* .rule, recoloured for this one dark context rather than cloned under a new
   name: same 1px/no-border primitive, just --rose instead of the --line
   default and narrowed to read as a divider rather than a full-width hairline. */
.home-editorial .rule {
  width: 48px;
  background: var(--rose);
}

/* .btn--ghost inverted for a burgundy field: the default border (--line) and
   label (--ink) would both sit near-invisibly close to burgundy in value. */
.home-editorial .btn--ghost {
  border-color: var(--rose);
  color: var(--cream);
}
.home-editorial .btn--ghost:hover {
  border-color: var(--cream);
  color: var(--cream);
  background: var(--burg-soft);
}

/* ---------- 5. Feature graphic ----------------------------------------------- */

.home-feature__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: var(--space-9);
}

/* feature_image() returning null (missing art, product data intact) collapses
   this to one centred column instead of a half-empty grid. */
.home-feature__grid--solo {
  grid-template-columns: 1fr;
  max-width: 56ch;
  margin-inline: auto;
}

.home-feature__media {
  border-radius: var(--radius-md);
}

.home-feature__copy {
  display: grid;
  gap: var(--space-4);
  justify-items: start;
}

@media (max-width: 899px) {
  .home-feature__grid { grid-template-columns: 1fr; gap: var(--space-6); }
}

/* ---------- 6. Closing CTA ---------------------------------------------------- */

.home-closing {
  background: var(--oat);
}

.home-closing__inner {
  display: grid;
  justify-items: center;
  gap: var(--space-5);
  max-width: 44ch;
  margin-inline: auto;
  text-align: center;
}

/* ---------- 7. Collection page (kolekcija.php) ------------------------------ */

.kolekcija-header {
  background: var(--oat);
}
.kolekcija-header__inner {
  display: grid;
  gap: var(--space-3);
}

.kolekcija-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: var(--space-6);
}

.kolekcija-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
}

/* flex-start, not center: .kolekcija-filters (Boja + Veličina's shared flex
   row) stretches both groups to equal height by default, and Veličina's
   block is now taller than one row (grouped size chips). center-aligning a
   shorter single-row group's own label against that taller stretched box
   sinks the label toward the middle instead of the top - invisible when
   every row was exactly one line, real now that one isn't. flex-start pins
   every row's label (and its own chips) to the row's own top edge, so Boja,
   Veličina and Sortiraj all start at the same y regardless of how tall any
   one of them grows - one rule for all three rather than a per-row fix. */
.kolekcija-control-group {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-2);
}

.kolekcija-control-group__label {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--taupe);
  margin-right: var(--space-1);
}

/* .size-pill, reused as a link instead of the JS-toggled button it was built
   for: the "current" look needs no script here because PHP already renders
   aria-current on whichever value the server validated and applied. Scoped
   under this page's toolbar so the shared component's own button behaviour
   (the product page's size selector) is untouched. */
.kolekcija-control-group .size-pill {
  text-decoration: none;
}
.kolekcija-control-group .size-pill[aria-current="true"] {
  background: var(--burgundy);
  border-color: var(--burgundy);
  color: var(--bone);
}

/* Size filter, grouped by garment family (see kolekcija.php's $sizeGroups)
   instead of one undifferentiated run of chips - "S" sitting directly next
   to "XS/S" with no explanation reads as a duplicate or a bug, not a
   second size scale. (No group-specific alignment override needed here -
   .kolekcija-control-group is flex-start by default, so this taller,
   multi-row block still starts flush with Boja's and Sortiraj's labels.) */
.kolekcija-size-groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.kolekcija-size-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.kolekcija-size-group__label {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  color: var(--taupe);
  margin-right: var(--space-1);
}

.kolekcija-color-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}
.kolekcija-color-pill__swatch {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: none;
  background: var(--swatch, transparent);
  box-shadow: 0 0 0 1px var(--line);
}
.kolekcija-color-pill[aria-current="true"] .kolekcija-color-pill__swatch {
  box-shadow: 0 0 0 1px var(--bone);
}

.kolekcija-active {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--line);
}

/* Same remove glyph as the drawer's close button and cart line remove button
   (identical path data) - one "remove/close" mark for the whole site rather
   than a typographic × that would carry a different weight. */
.filter-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: .4rem var(--space-3) .4rem var(--space-4);
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--oat);
  color: var(--ink);
  font-size: var(--step--2);
  letter-spacing: .03em;
  text-decoration: none;
  transition: border-color 200ms var(--ease), color 200ms var(--ease);
}
.filter-pill:hover {
  border-color: var(--burgundy);
  color: var(--burgundy);
}
.filter-pill__icon {
  width: 11px;
  height: 11px;
  flex: none;
}

.kolekcija-clear {
  margin-left: auto;
  font-size: var(--step--2);
  letter-spacing: .03em;
}

.kolekcija-empty {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  padding-block: var(--space-11);
  text-align: center;
}

@media (max-width: 619px) {
  .kolekcija-toolbar { flex-direction: column; align-items: stretch; }
  .kolekcija-clear { margin-left: 0; }
}

/* ---------- 8. Product page (proizvod.php) ----------------------------------- */

.pd-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: start;
  gap: var(--space-9);
}

/* ---- 8.1 Gallery ----
   Every slide is real, server-rendered markup - all six ship in the HTML
   regardless of JavaScript (see the six <figure> loop in proizvod.php).
   Only once `.js` lands on <html> (header.php, before first paint) does this
   narrow to one image at a time via [data-active]; a no-JS visitor instead
   gets all six stacked in one scrollable column, the same degrade-gracefully
   approach components.css already uses for blur-up images. */
.pd-gallery {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.pd-gallery__stage {
  border-radius: var(--radius-md);
  overflow: hidden;
}

.pd-gallery__slide + .pd-gallery__slide { margin-top: var(--space-3); }
.js .pd-gallery__slide { display: none; }
.js .pd-gallery__slide[data-active] { display: block; }

/* min-width:0 overrides the flex default of min-width:auto, which sizes a
   flex item to its content's intrinsic width no matter what - six 64px
   thumbnails plus gaps (444px) is wider than a 360px viewport's content
   column, and without this the row refused to shrink and pushed the whole
   page wide instead of scrolling within itself. Same trap, same fix, as the
   home hero grid's own min-width:0 note in this file. */
.pd-gallery__thumbs {
  display: flex;
  flex-direction: row;
  gap: var(--space-3);
  overflow-x: auto;
  padding-bottom: var(--space-1);
  min-width: 0;
}

.pd-thumb {
  flex: none;
  width: 64px;
  aspect-ratio: 2 / 3;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--oat);
  cursor: pointer;
  transition: border-color 200ms var(--ease), box-shadow 200ms var(--ease);
}
.pd-thumb__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.pd-thumb:hover { border-color: var(--burgundy); }
.pd-thumb[aria-current="true"] {
  border-color: var(--burgundy);
  box-shadow: 0 0 0 1px var(--burgundy);
}

/* Vertical strip beside the main image on desktop, horizontal strip below it
   on mobile (the brief's explicit split) - row-reverse keeps DOM order
   [stage, thumbs] (main photo first - the more useful no-JS/screen-reader
   reading order) while placing thumbs visually first, to the left. */
@media (min-width: 900px) {
  .pd-gallery { flex-direction: row-reverse; }
  .pd-gallery__stage { flex: 1; min-width: 0; }
  .pd-gallery__thumbs {
    flex-direction: column;
    width: 76px;
    flex: none;
    overflow-x: visible;
    overflow-y: auto;
    max-height: 640px;
  }
  .pd-thumb { width: 100%; }
}

/* ---- 8.2 Buy box ---- */

.pd-buybox {
  display: grid;
  gap: var(--space-5);
  align-content: start;
}

/* --pd-sticky-top is measured live against the real header height by
   product.js (the header's own height already varies slightly by content,
   and this avoids guessing a pixel figure that drifts out of sync with it -
   the same problem ui.js already solves for the mobile menu's own offset).
   The token fallback only covers the instant before that script runs. */
@media (min-width: 900px) {
  .pd-buybox { position: sticky; top: var(--pd-sticky-top, 6rem); }
}

.pd-buybox__badge {
  display: inline-flex;
  width: fit-content;
  padding: .3rem var(--space-3);
  background: var(--burgundy);
  color: var(--cream);
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.pd-buybox__name {
  font-family: var(--font-display);
  font-size: var(--step-5);
}

.pd-buybox__price {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--step-3);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.pd-buybox__price--sale span:last-child { color: var(--wine); }
.pd-buybox__compare {
  font-family: var(--font-ui);
  font-size: var(--step-0);
  font-weight: 400;
  color: var(--stone);
}

.pd-buybox__rating {
  margin-top: calc(var(--space-3) * -1);
  font-size: var(--step--1);
  color: var(--taupe);
  font-variant-numeric: tabular-nums;
}
.pd-buybox__rating span { color: var(--stone); }

.pd-buybox__group { display: grid; gap: var(--space-3); }
.pd-buybox__group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}
.pd-buybox__label {
  font-family: var(--font-ui);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--taupe);
}
/* The live-updating colour name sits inside the label ("Boja - Karamel") but
   reads as a value, not a shouted micro-label, so it opts back out of the
   uppercase/tracking the rest of the label sets. */
.pd-buybox__label span {
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink);
}
.pd-buybox__sizeguide { font-size: var(--step--2); }

.pd-swatches,
.pd-sizes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.pd-buybox__hint {
  font-size: var(--step--2);
  color: var(--wine);
}

/* ---- 8.3 Accordion (Opis / Sastav i nega / Dostava i povraćaj) ----
   Native <details>/<summary>: full keyboard and screen-reader support with
   no JavaScript at all, and every panel's content is already in the HTML
   (collapsed, not absent) even before .js lands on <html>. */

.pd-details__inner { max-width: 68ch; }

.pd-accordion__item { border-bottom: 1px solid var(--line); }
.pd-accordion__item:first-child { border-top: 1px solid var(--line); }

.pd-accordion__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-5);
  font-family: var(--font-display);
  font-size: var(--step-2);
  cursor: pointer;
  list-style: none;
}
.pd-accordion__summary::-webkit-details-marker { display: none; }
.pd-accordion__summary:hover { color: var(--burgundy); }

.pd-accordion__chevron {
  flex: none;
  width: 18px;
  height: 18px;
  color: var(--taupe);
  transition: transform 240ms var(--ease);
}
.pd-accordion__item[open] .pd-accordion__chevron { transform: rotate(180deg); }

.pd-accordion__panel {
  display: grid;
  gap: var(--space-3);
  padding-bottom: var(--space-6);
  color: var(--taupe);
  font-size: var(--step--1);
  line-height: 1.6;
}
.pd-accordion__list {
  display: grid;
  gap: var(--space-2);
  padding-left: var(--space-5);
}

/* ---- 8.4 Feature graphic ----
   feature_image() returns native width/height (750 or 800 depending on the
   source art) and .media--auto (components.css) resolves aspect-ratio from
   those attributes instead of forcing the 2:3 product-photo ratio - the
   graphics measured 800x438 through 800x1067, nowhere near uniform. */

.pd-feature__inner {
  display: grid;
  justify-items: center;
  gap: var(--space-5);
  max-width: 46ch;
  margin-inline: auto;
  text-align: center;
}
.pd-feature__media {
  width: 100%;
  max-width: 30rem;
  border-radius: var(--radius-md);
}

/* ---- 8.5 Related products ----
   auto-fit (not .product-grid's own auto-fill) collapses the unused track
   instead of leaving a gap: with exactly 3 cards this always yields 3 even
   columns rather than the 4-up/3-populated orphan Task 7 hit on the home
   page's featured grid - no item-count-specific column rule to keep in sync. */
.pd-related__grid {
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}

/* ---- 8.6 Not-found (404) ---- */

.pd-notfound__inner {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  padding-block: var(--space-11);
  text-align: center;
}

@media (max-width: 899px) {
  /* minmax(0, 1fr), not a bare 1fr: an implicit grid track's minimum is
     "auto" (content-based) unless told otherwise, same trap as a flex
     item's default min-width:auto just one layer up - see the
     .pd-gallery__thumbs comment below for the concrete number that exposed
     this (six 64px thumbnails read as a 444px content floor, wider than a
     360px viewport's content column, so the bare 1fr track refused to
     shrink and forced horizontal overflow on the whole page). */
  .pd-layout { grid-template-columns: minmax(0, 1fr); }
  .pd-buybox { position: static; }

  .pd-gallery__thumbs { max-height: none; }
}

/* ---------- 9. Cart page (korpa.php) -----------------------------------
   The cart lives only in localStorage, so every line item and rail figure
   below is rendered by assets/js/cart-page.js, not PHP - this file only
   lays out the shell that script fills in. .cart-line, .qty-stepper,
   .ship-meter and .totals are the exact components.css parts the header
   drawer already uses (see ui.js's own renderLine/renderSummary); only
   their arrangement is page-specific here, via scoped overrides rather
   than edits to those shared rules. */

.korpa-intro__inner {
  display: grid;
  gap: var(--space-3);
}

/* .korpa-intro (.section--sm) already carries its own bottom padding.
   Kolekcija.php stacks the same way, but its toolbar fills the seam between
   sections - this page has nothing there, so the full .section top padding
   underneath reads as an accidental gap rather than a considered one.
   Tightened on top only; the bottom padding before the footer is untouched. */
.korpa-section {
  padding-top: var(--space-8);
}

/* Hidden by default (JavaScript is assumed); .no-js is the one case where
   the cart genuinely cannot render, since its contents live only in
   localStorage - same class-swap technique base.css's own blur-up images
   and components.css's mobile nav already rely on. */
.korpa-nojs {
  display: none;
  max-width: 46ch;
  color: var(--taupe);
}
.no-js .korpa-nojs { display: block; }

.korpa-empty {
  display: grid;
  justify-items: start;
  gap: var(--space-5);
  padding-block: var(--space-9);
}
.korpa-empty p { color: var(--taupe); }

.korpa-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
  align-items: start;
  gap: var(--space-9);
}

/* Wider than the drawer's 64px column - the full page has room to spare,
   and minmax(0, ...) on the body column (not a bare 1fr) keeps a long
   price/stepper row from forcing the whole page wider at narrow widths,
   the same trap documented above for .pd-layout. */
.korpa-lines .cart-line {
  grid-template-columns: 120px minmax(0, 1fr) auto;
}

.korpa-rail {
  display: grid;
  gap: var(--space-6);
  padding: var(--space-6);
  background: var(--oat);
  border-radius: var(--radius-md);
}
.korpa-rail__heading {
  margin: 0;
}

/* --korpa-sticky-top is measured live against the real header height by
   cart-page.js - same technique as --pd-sticky-top above, so the summary
   card tracks the header's actual height instead of a guessed constant. */
@media (min-width: 900px) {
  .korpa-rail { position: sticky; top: var(--korpa-sticky-top, 6rem); }
}

@media (max-width: 899px) {
  .korpa-layout { grid-template-columns: minmax(0, 1fr); }
  .korpa-lines .cart-line { grid-template-columns: 96px minmax(0, 1fr) auto; }
}

/* Below ~480px the qty-stepper (fixed-width, three controls) and the
   nowrap price no longer both fit the row's shrunken share of a 360px
   viewport - verified live, not assumed. Wrapping the row is a safer fix
   than shrinking the stepper's own buttons below a tappable size. */
@media (max-width: 479px) {
  .korpa-lines .cart-line { grid-template-columns: 80px minmax(0, 1fr) auto; }
  .korpa-lines .cart-line__row { flex-wrap: wrap; row-gap: var(--space-2); }
}

/* ---------- 10. Checkout page (placanje.php) -----------------------------
   Same shell pattern as the cart page: a two-column layout (form + a
   sticky review rail), hidden until assets/js/checkout.js confirms there is
   something to check out and reveals it - see .checkout-nojs below for why
   the form itself is never shown without JavaScript. .cart-line and .totals
   are the same components.css parts korpa.php and the drawer already use;
   only .checkout-payment is new, and potvrda.php (section 11 below) reuses
   it verbatim rather than duplicating it. */

.checkout-intro__inner {
  display: grid;
  gap: var(--space-3);
}

.checkout-section {
  padding-top: var(--space-8);
}

.checkout-nojs {
  display: none;
  max-width: 46ch;
  color: var(--taupe);
}
.no-js .checkout-nojs { display: block; }

.checkout-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 400px);
  align-items: start;
  gap: var(--space-9);
}

.checkout-form {
  display: grid;
  gap: var(--space-8);
}
/* Native fieldset/legend chrome reset - spacing between sections comes from
   .checkout-form's own gap instead. */
.checkout-form fieldset {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}
.checkout-form legend {
  padding: 0;
  width: 100%;
}

.checkout-fieldset__legend {
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--taupe);
  margin-bottom: var(--space-5);
}

/* Ime/Adresa/Napomena take the full row (.form-field--full); Telefon+Email
   and Grad+Poštanski broj pair up two-per-row via plain grid auto-flow -
   still emitted in inc/validation.php's own CUSTOMER_FIELDS order in the
   markup, this only changes how adjacent fields lay out visually. */
.checkout-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
}
.checkout-grid .form-field--full { grid-column: 1 / -1; }

@media (max-width: 619px) {
  .checkout-grid { grid-template-columns: 1fr; }
}

/* The locked payment block: an explained statement of fact, not a fake
   radio group with one option. panel--cream is the sitewide sanctioned
   cream surface (bounded by a burgundy edge, so cream never touches bone);
   this only overrides its padding for a more compact card. Reused as-is by
   potvrda.php below. */
.checkout-payment__option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-6);
}
.checkout-payment__icon {
  flex: none;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  color: var(--burgundy);
}
.checkout-payment__title {
  font-family: var(--font-ui);
  font-weight: 500;
  color: var(--ink);
}
.checkout-payment__desc {
  margin-top: var(--space-1);
  font-size: var(--step--1);
  color: var(--taupe);
}

.checkout-submit { margin-top: var(--space-1); }

/* Error summary, focused programmatically (tabindex="-1") by checkout.js
   when a failure is not tied to any single field (CSRF/JSON/DB failures) or
   right after a server-rendered re-render. --wine is the sitewide error
   voice already used by .form-field__error; no new colour introduced. */
.checkout-alert {
  padding: var(--space-5) var(--space-6);
  border: 1px solid var(--wine);
  border-radius: var(--radius-md);
  background: var(--bone);
  display: grid;
  gap: var(--space-2);
}
.checkout-alert__title {
  color: var(--wine);
  font-weight: 500;
}
.checkout-alert__list {
  margin: 0;
  padding-left: var(--space-5);
  color: var(--taupe);
  font-size: var(--step--1);
}

/* Right rail: read-only order review. Narrower thumbnail than korpa's own
   (this is a summary, not the primary content) and only two grid columns -
   no remove button, so the shared .cart-line's third (auto) track is simply
   never populated. */
.checkout-summary {
  display: grid;
  gap: var(--space-6);
  padding: var(--space-6);
  background: var(--oat);
  border-radius: var(--radius-md);
}
.checkout-summary__heading { margin: 0; }
.checkout-lines .cart-line { grid-template-columns: 64px minmax(0, 1fr); }

@media (min-width: 900px) {
  .checkout-summary { position: sticky; top: var(--checkout-sticky-top, 6rem); }
}

@media (max-width: 899px) {
  .checkout-layout { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- 11. Confirmation page (potvrda.php) ---------------------------
   The order number is sequential and guessable, so this page renders only
   what the buyer already knows - items, sizes, quantities, total - never
   the phone number or full address (see potvrda.php's own comment at the
   point $order is first read). */

.confirm-hero {
  background: var(--oat);
}
.confirm-hero__inner {
  display: grid;
  gap: var(--space-3);
}
.confirm-number {
  font-family: var(--font-display);
  font-size: var(--step-3);
  color: var(--burgundy);
}

.confirm-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
  align-items: start;
  gap: var(--space-9);
}

.confirm-lines__heading { margin-bottom: var(--space-5); }
/* Same 2-column, no-remove-button treatment as the checkout review rail. */
.confirm-lines .cart-line { grid-template-columns: 72px minmax(0, 1fr); }

.confirm-summary {
  display: grid;
  gap: var(--space-6);
  padding: var(--space-6);
  background: var(--oat);
  border-radius: var(--radius-md);
}

@media (max-width: 899px) {
  .confirm-layout { grid-template-columns: minmax(0, 1fr); }
}

.confirm-notfound__inner {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  padding-block: var(--space-11);
  text-align: center;
}

/* ---------- 12. Admin dashboard (admin/login.php, admin/index.php) --------
   The only pages on the site that do not call render_header()/render_footer()
   - once a request is behind require_admin() there is no reason to ship the
   storefront's promo strip, cart drawer or product nav, so both pages build
   their own minimal shell directly in the page file. Still built from the
   same tokens as everywhere else: --oat cards, burgundy accents, nothing
   introduced outside tokens.css. */

/* ---- 12.1 Auth card (login.php) ----
   monogram-256.webp ships as a flat --cream circle with no transparent
   margin - placed straight onto this page's --bone background it would be
   the exact forbidden 1.002:1 bone/cream seam tokens.css documents (the same
   issue Task 6 hit with the wordmark raster on the --bone header). The
   box-shadow ring is the same technique .swatch[aria-pressed] and
   .pd-thumb[aria-current] already use: --burgundy sits flush against the
   cream circle (a sanctioned edge, like .panel--cream's border) and is what
   actually touches the page, so bone never meets cream directly. */
.admin-auth {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--space-6);
}
.admin-auth__card {
  width: min(26rem, 100%);
  display: grid;
  gap: var(--space-6);
  justify-items: center;
  padding: var(--space-9) var(--space-8);
  background: var(--oat);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  text-align: center;
}
.admin-auth__seal {
  display: block;
  width: 84px;
  height: 84px;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 0 0 3px var(--burgundy);
}
.admin-auth__seal img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.admin-auth__title {
  font-size: var(--step-4);
}
.admin-auth__form {
  width: 100%;
  display: grid;
  gap: var(--space-5);
  text-align: left;
}
.admin-auth__back {
  font-size: var(--step--1);
}

@media (max-width: 479px) {
  .admin-auth__card { padding: var(--space-7) var(--space-6); }
}

/* ---- 12.2 Top bar (index.php) ----
   Burgundy, not --bone like the rest of the site's header - a deliberate
   break from the storefront chrome so a merchant can never mistake this for
   a public page. Same inverted-ghost-button and rose-focus-ring treatment
   already proven on a burgundy field by .home-editorial and .site-footer. */
.admin-bar {
  background: var(--burgundy);
  color: var(--cream);
}
.admin-bar :focus-visible {
  outline-color: var(--rose);
}
.admin-bar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding-block: var(--space-4);
}
.admin-bar__brand {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
}
.admin-bar__mark {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 600;
  letter-spacing: .03em;
  color: var(--cream);
}
.admin-bar__tag {
  font-size: var(--step--2);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--rose);
}
.admin-bar__meta {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}
.admin-bar__unfulfilled {
  font-size: var(--step--1);
  letter-spacing: .02em;
  color: var(--cream);
}
.admin-bar__unfulfilled strong {
  font-family: var(--font-display);
  font-size: var(--step-1);
}
.admin-bar__logout {
  border-color: var(--rose);
  color: var(--cream);
}
.admin-bar__logout:hover {
  border-color: var(--cream);
  background: var(--burg-soft);
  color: var(--cream);
}

@media (max-width: 619px) {
  .admin-bar__inner { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
  .admin-bar__meta { width: 100%; justify-content: space-between; }
}

/* ---- 12.3 Intro, flash, toolbar ---- */
.admin-intro__inner {
  display: grid;
  gap: var(--space-3);
}

/* Same tightened-seam pattern as .korpa-section/.checkout-section: the
   intro band above already carries its own bottom padding via .section--sm,
   so the full .section top padding here would read as an accidental gap. */
.admin-content {
  padding-top: var(--space-8);
}

.admin-flash {
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  font-size: var(--step--1);
  margin-bottom: var(--space-6);
}
.admin-flash--ok {
  background: var(--oat);
  border: 1px solid var(--line);
  color: var(--ink);
}
.admin-flash--error {
  background: var(--bone);
  border: 1px solid var(--wine);
  color: var(--wine);
}

.admin-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-6);
  margin-bottom: var(--space-6);
}
.admin-status-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
/* .size-pill reused bare as a link (same technique as
   .kolekcija-control-group's own copy of this override): the shared
   component only styles [aria-pressed] for its native JS-toggle-button use
   on the product page, so an <a> needs its underline removed explicitly, and
   the "current filter" look needs [aria-current="true"] added explicitly -
   scoped to this toolbar so the shared component itself stays untouched. */
.admin-status-filters .size-pill {
  text-decoration: none;
}
.admin-status-filters .size-pill[aria-current="true"] {
  background: var(--burgundy);
  border-color: var(--burgundy);
  color: var(--bone);
}

.admin-search {
  display: flex;
  align-items: start;
  gap: var(--space-3);
}
.admin-search__field {
  width: min(20rem, 60vw);
}

/* Same removable-pill row as kolekcija.php's own filter summary, kept as a
   page-scoped copy rather than a cross-page reuse of .kolekcija-active/
   .kolekcija-clear - .size-pill and .filter-pill themselves are the actual
   shared components and are reused bare, below and above. */
.admin-active {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid var(--line);
}
.admin-clear {
  margin-left: auto;
  font-size: var(--step--2);
  letter-spacing: .03em;
}

@media (max-width: 619px) {
  .admin-toolbar { flex-direction: column; align-items: stretch; }
  .admin-search__field { width: 100%; }
  .admin-clear { margin-left: 0; }
}

/* ---- 12.4 Order cards ---- */
.admin-orders {
  display: grid;
  gap: var(--space-6);
}
.admin-order {
  background: var(--oat);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6) var(--space-7);
  display: grid;
  gap: var(--space-5);
  scroll-margin-top: var(--space-6);
}

.admin-order__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--line);
}
.admin-order__number {
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--burgundy);
}
.admin-order__date,
.admin-order__updated {
  margin-top: var(--space-1);
  font-size: var(--step--2);
  color: var(--taupe);
}

/* Deliberately restrained to three tones, not five - the palette's own rule
   is that burgundy is the only saturated colour and appears only where
   attention is earned. "active" (nova/potvrdjena/poslata) still needs the
   merchant's attention; "done" and "cancelled" are both resolved and only
   differ in outcome, so they borrow the site's existing neutral and error
   voices (--taupe, --wine) rather than inventing two more colours. */
.admin-badge {
  display: inline-flex;
  flex: none;
  padding: .3rem var(--space-3);
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-size: var(--step--2);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
}
.admin-badge--active {
  background: var(--burgundy);
  color: var(--cream);
}
.admin-badge--done {
  background: var(--bone);
  color: var(--taupe);
  border: 1px solid var(--line);
}
.admin-badge--cancelled {
  background: var(--bone);
  color: var(--wine);
  border: 1px solid var(--wine);
}

.admin-order__body {
  display: grid;
  grid-template-columns: minmax(220px, 320px) minmax(0, 1fr);
  gap: var(--space-7);
}

.admin-order__customer {
  display: grid;
  gap: var(--space-2);
  align-content: start;
}
.admin-order__name {
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--ink);
}
.admin-order__address {
  color: var(--taupe);
  font-size: var(--step--1);
}
.admin-order__copy {
  justify-self: start;
  padding: 0;
  border: 0;
  /* background-color, not the `background` shorthand: this reuses .link
     (see components.css), whose hover underline is a background-image
     (a 1px gradient revealed by animating background-size). The shorthand
     would reset that image to none - pages.css loads after components.css,
     so at equal specificity it would silently win and the button would lose
     the underline every other .link on the site has. */
  background-color: transparent;
  font: inherit;
  font-size: var(--step--2);
  cursor: pointer;
}
.admin-order__note {
  margin-top: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--bone);
  border-radius: var(--radius-sm);
  font-size: var(--step--1);
  color: var(--ink);
  line-height: 1.5;
}

.admin-order__items {
  display: grid;
  gap: var(--space-3);
  align-content: start;
}
.admin-order__item {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-3);
}
.admin-order__thumb {
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.admin-order__item-name {
  font-size: var(--step--1);
  color: var(--ink);
}
.admin-order__item-meta {
  font-size: var(--step--2);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--taupe);
}
.admin-order__item-price {
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.admin-order__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
}
.admin-order__total {
  font-size: var(--step--1);
  color: var(--taupe);
}
.admin-order__total strong {
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--ink);
  font-weight: 400;
}
.admin-order__status-form {
  display: flex;
  align-items: end;
  gap: var(--space-3);
}
.admin-order__status-field {
  min-width: 11rem;
}

.admin-empty {
  display: grid;
  justify-items: center;
  gap: var(--space-4);
  padding-block: var(--space-11);
  text-align: center;
}

/* This is the owner's only view of their orders (see ADMIN_PAGE_SIZE in
   admin/index.php) - Prethodna/Sledeća stay real, styled <a> elements when a
   page exists to go to, and drop to an inert <span class="btn btn--ghost"
   aria-disabled="true"> at either end, reusing .btn--ghost[aria-disabled]'s
   existing "stone" disabled voice rather than a live link nothing happens on. */
.admin-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
  margin-top: var(--space-8);
}
.admin-pagination__status {
  font-size: var(--step--1);
  color: var(--taupe);
  white-space: nowrap;
}
.admin-pagination__step {
  min-width: 8rem;
}

@media (max-width: 479px) {
  .admin-pagination { gap: var(--space-3); }
  .admin-pagination__step { min-width: 0; padding-inline: var(--space-4); }
  .admin-pagination__status { font-size: var(--step--2); }
}

@media (max-width: 899px) {
  .admin-order__body { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 619px) {
  .admin-order { padding: var(--space-5); }
  .admin-order__head { flex-wrap: wrap; }
}

@media (max-width: 479px) {
  .admin-order__item { grid-template-columns: 40px minmax(0, 1fr); }
  .admin-order__item-price { grid-column: 2; padding-left: calc(40px + var(--space-3)); }
  .admin-order__foot { flex-direction: column; align-items: stretch; }
  .admin-order__status-form { flex-direction: column; align-items: stretch; }
}

/* ==================================================================
   10. Size guide (velicine.php) and About (o-nama.php)
   ================================================================== */

.velicine-header,
.onama-header { background: var(--oat); }

/* These classes sit ON the .container element itself, which supplies both
   the centring margin and the gutter padding. Setting max-width or margin
   here would fight that and knock the heading out of line with every
   section below. Constrain the reading measure on the children only. */
.velicine-header__inner h1,
.onama-header__inner h1 { max-width: 18ch; }

.velicine-header__inner .lede,
.onama-header__inner .lede { max-width: 56ch; }

.onama-header__inner .eyebrow { margin-bottom: var(--space-3); }

/* --- How to measure ---------------------------------------------- */

.measure-steps {
  list-style: none;
  margin: 0 0 var(--space-8);
  padding: 0;
  display: grid;
  gap: var(--space-7);
  grid-template-columns: repeat(3, 1fr);
}

.measure-steps > li { border-top: 1px solid var(--line); padding-top: var(--space-4); }

.measure-steps__num {
  display: block;
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--burg-soft);
  line-height: 1;
  margin-bottom: var(--space-3);
}

.measure-steps h3 {
  font-family: var(--font-ui);
  font-size: var(--step-0);
  font-weight: 500;
  letter-spacing: .02em;
  margin: 0 0 var(--space-2);
}

.measure-steps p { color: var(--taupe); margin: 0; }

.measure-note {
  border-left: 2px solid var(--burgundy);
  padding-left: var(--space-4);
  color: var(--ink);
  max-width: 58ch;
  margin: 0;
}

/* --- Size tables -------------------------------------------------- */

.size-intro { max-width: 62ch; margin-bottom: var(--space-6); }

.size-table-wrap { margin-bottom: var(--space-4); }

.size-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.size-table thead th {
  background: var(--burgundy);
  color: var(--cream);
  font-family: var(--font-ui);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-align: left;
  padding: var(--space-3) var(--space-4);
}

.size-table__unit {
  text-transform: none;
  letter-spacing: 0;
  opacity: .75;
  font-size: .9em;
}

.size-table tbody th,
.size-table tbody td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  font-weight: 400;
}

.size-table tbody th { font-weight: 500; }
.size-table tbody tr:nth-child(odd)  { background: var(--bone); }
.size-table tbody tr:nth-child(even) { background: var(--oat); }

.size-footnote {
  color: var(--taupe);
  font-size: var(--step--1);
  max-width: 60ch;
  margin: 0;
}

/* --- Pending-chart panel ------------------------------------------ */

.size-pending { max-width: 68ch; }
.size-pending p { margin: 0 0 var(--space-3); }
.size-pending p:last-child { margin-bottom: 0; }

.size-pending__list {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  display: grid;
  gap: var(--space-2);
  color: var(--taupe);
  font-size: var(--step--1);
}

.care-list {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
  display: grid;
  gap: var(--space-2);
  max-width: 40ch;
}

.care-list li {
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--space-2);
  color: var(--ink);
}

/* --- About -------------------------------------------------------- */

.about-hero .media--hero { border-radius: var(--radius-lg); overflow: hidden; }

.about-story__body { max-width: 62ch; }
.about-story__body p { color: var(--taupe); margin: 0 0 var(--space-4); }
.about-story__body p:last-child { margin-bottom: 0; }

.about-values { background: var(--burgundy); padding-block: var(--space-10); }

.about-values__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-7);
  grid-template-columns: repeat(3, 1fr);
}

.about-values__list h3 {
  font-family: var(--font-display);
  font-size: var(--step-2);
  color: var(--cream);
  margin: 0 0 var(--space-3);
}

.about-values__list p { color: var(--rose); margin: 0; }

/* --- Responsive --------------------------------------------------- */

@media (max-width: 899px) {
  .measure-steps,
  .about-values__list { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 639px) {
  .measure-steps,
  .about-values__list { grid-template-columns: 1fr; }

  /* The table becomes stacked cards rather than scrolling sideways.
     Each cell carries its own label via data-label, so the header row
     can be hidden without losing meaning. */
  .size-table thead { position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

  .size-table,
  .size-table tbody,
  .size-table tr,
  .size-table th,
  .size-table td { display: block; width: 100%; }

  .size-table tbody tr {
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-4);
    padding: var(--space-2) var(--space-4);
  }

  .size-table tbody th {
    font-family: var(--font-display);
    font-size: var(--step-1);
    padding: var(--space-3) 0 var(--space-2);
    border-bottom: 1px solid var(--line);
  }

  .size-table tbody td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-2) 0;
  }

  .size-table tbody td::before {
    content: attr(data-label);
    color: var(--taupe);
    font-size: var(--step--1);
  }

  .size-table tbody th[data-label]::before { content: none; }
}
