/* ==========================================================================
   Larisel furniture — the configurator: a lit stage on the left where the
   piece stands, and a paper spec sheet on the right where it is specified.
   (Tokens, fonts and reset: css/base.css.)
   ========================================================================== */

.app {
  height: calc(100svh - var(--head-h));
  min-height: 560px;
  display: grid;
  grid-template-columns: 1fr minmax(360px, 430px);
}

/* --- Stage ---------------------------------------------------------------- */

.stage {
  position: relative;
  min-width: 0;
  /* A room, not a swatch: light falls from above and behind the product, and
     the corners drop away. A flat fill is what makes a render look pasted. */
  background:
    radial-gradient(120% 86% at 50% 4%, var(--bg-warm) 0%, var(--bg) 52%, var(--bg-deep) 100%);
}

/* Vignette and grain, in that order. Both are one element each and they do
   more for the sense of a photographed room than any amount of extra light
   in the scene. */
.stage::before,
.stage::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.stage::before {
  background: radial-gradient(78% 62% at 50% 46%, transparent 48%, rgba(25, 20, 16, 0.13) 100%);
}
.stage::after {
  opacity: 0.35;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.2'/%3E%3C/svg%3E");
}

.stage canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: grab;
  opacity: 0;
  transition: opacity 1.2s var(--e-out);
}
.stage canvas:active { cursor: grabbing; }
body.is-ready .stage canvas { opacity: 1; }

.stage-top,
.stage-bottom {
  position: absolute;
  z-index: 2;
  display: flex;
  gap: 16px;
}
.stage-top {
  inset: 26px 26px auto 26px;
  align-items: flex-start;
  justify-content: space-between;
}
.stage-bottom {
  inset: auto 26px 26px 26px;
  align-items: flex-end;
  justify-content: space-between;
}

/* The brand lockup. The product name lives here, in the serif, so the panel
   beside it can stay a spec sheet instead of also being a poster. */
.mark {
  display: grid;
  gap: 2px;
  pointer-events: none;
}
/* light type: the studio's sweep rises into shadow behind it in every frame */
.mark__name {
  font-family: var(--f-display);
  font-size: 1.25rem;
  letter-spacing: 0.01em;
  line-height: 1;
  color: #f7f2e9;
  text-shadow: 0 1px 12px rgba(40, 30, 20, 0.35);
}
.mark__sub {
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: rgba(247, 242, 233, 0.72);
}
/* the coffee table is seen from higher: the lit floor is behind the mark, so the
   type turns to ink as that piece dissolves in */
.mark__name, .mark__sub { transition: color 620ms var(--e-out), text-shadow 620ms var(--e-out); }
.stage[data-ground="light"] .mark__name { color: var(--ink); text-shadow: 0 1px 10px rgba(253, 251, 247, 0.45); }
.stage[data-ground="light"] .mark__sub { color: var(--ink-soft); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-fine);
  color: var(--ink-soft);
  background: rgba(253, 251, 247, 0.72);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-pill);
  padding: 8px 15px;
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow-sm);
}
.chip--mono {
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: 0.1em;
  color: var(--muted);
}

/* Language. Same control as the rest of the portfolio, so a visitor who
   arrives from larisel.com meets something they have already used. */
.hint {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: var(--t-fine);
  color: var(--muted);
  opacity: 0;
  transition: opacity 800ms var(--e-out);
}
body.is-ready .hint { opacity: 1; }
body.is-turned .hint { opacity: 0; }
.hint svg {
  width: 16px; height: 16px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: nudge 3.6s var(--e-out) infinite;
}
@keyframes nudge {
  0%, 64%, 100% { transform: rotate(0deg); }
  78%           { transform: rotate(-30deg); }
}

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

.tool {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--t-fine);
  color: var(--ink-soft);
  background: rgba(253, 251, 247, 0.72);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-pill);
  padding: 9px 15px;
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow-sm);
  transition: background var(--d-fast) var(--e-out),
              color var(--d-fast) var(--e-out),
              transform var(--d-fast) var(--e-out);
}
.tool:hover { background: var(--panel); color: var(--ink); transform: translateY(-2px); }
.tool svg {
  width: 15px; height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}


/* --- Panel ---------------------------------------------------------------- */

.panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel);
  border-left: 1px solid var(--line-soft);
  box-shadow: -1px 0 0 var(--line-hair), -24px 0 60px -30px rgba(25, 20, 16, 0.25);
}

.panel-head {
  padding: 34px 32px 24px;
  border-bottom: 1px solid var(--line-soft);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.eyebrow::before {
  content: "";
  width: 24px; height: 1px;
  background: var(--accent);
  flex: none;
}

.panel-head h1 {
  margin: 14px 0 10px;
  font-family: var(--f-display);
  font-size: var(--t-h1);
  font-weight: 400;
  font-optical-sizing: auto;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.lede {
  font-size: var(--t-fine);
  line-height: 1.55;
  color: var(--muted);
  max-width: 38ch;
}

.panel-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 32px 22px;
  /* A scroll container that ends flush with a border looks cut off. */
  mask-image: linear-gradient(to bottom, transparent 0, #000 14px,
                              #000 calc(100% - 14px), transparent 100%);
}

.group {
  padding: 22px 0;
  border-bottom: 1px solid var(--line-hair);
}
.group:last-child { border-bottom: 0; }

.group-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 15px;
}
.group-head h2 {
  font-family: var(--f-body);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}
.group-value {
  font-size: var(--t-fine);
  color: var(--muted);
  text-align: right;
}

/* --- Swatches -------------------------------------------------------------
   The colour itself is the label; the name appears on hover. Twelve named
   buttons would not fit the column, and twelve unnamed dots are a guessing
   game — the tooltip is the cheapest way out of that trade.
   Six to a row at every width, so twelve colours are two even rows (a
   wrapping row broke them 5 + 5 + 2 in a 360px panel): the columns give
   up a few pixels before a swatch moves down. */

.swatches { display: grid; grid-template-columns: repeat(6, minmax(0, 44px)); gap: 11px; }
/* the frames: four woods over four metals */
.swatches--4 { grid-template-columns: repeat(4, minmax(0, 44px)); }

.swatch {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  /* a rendered ball of the material itself (renders/swatch/): the boucle's
     loops, the oak's rings, the metal's softbox — the colour underneath is
     only there until it arrives */
  background-size: cover;
  background-position: center;
  box-shadow: 0 1px 2px rgba(25, 20, 16, 0.14);
  transition: transform var(--d-fast) var(--e-out),
              box-shadow var(--d-fast) var(--e-out);
}
.swatch:hover { transform: translateY(-2px) scale(1.06); }
.swatch.is-active {
  box-shadow: 0 0 0 2px var(--panel),
              0 0 0 3px var(--ink);
}

.swatch::after {
  content: attr(data-name);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 9px);
  transform: translateX(-50%);
  padding: 4px 9px;
  border-radius: var(--r-sm);
  background: var(--ink);
  color: var(--panel);
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: 0.05em;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--d-fast) var(--e-out);
  z-index: 4;
}
.swatch:hover::after,
.swatch:focus-visible::after { opacity: 1; }
/* the outer columns' names lean inwards: centred, "Brushed nickel · +$220"
   ran out of the panel's left edge and was cut by it */
.swatches:not(.swatches--4):not(.swatches--8) .swatch:nth-child(6n + 1)::after,
.swatches--4 .swatch:nth-child(4n + 1)::after { left: 0; transform: none; }
.swatches:not(.swatches--4):not(.swatches--8) .swatch:nth-child(6n)::after,
.swatches--4 .swatch:nth-child(4n)::after { left: auto; right: 0; transform: none; }

/* --- Pairings --------------------------------------------------------------
   A chair, a cushion and a frame chosen together: a small render of the
   chair dressed in them, the name, and the three materials. One tap sets all
   three; the rows below stay in charge. */

.pairs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }

.pair {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 6px 10px 6px 6px;
  background: var(--panel-2);
  border: 1px solid var(--line-hair);
  border-radius: var(--r-md);
  text-align: left;
  transition: border-color var(--d-fast) var(--e-out), box-shadow var(--d-fast) var(--e-out);
}
.pair:hover { border-color: var(--line); }
.pair.is-active { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }

.pair-thumb {
  flex: none;
  width: 56px;
  height: 56px;
  border-radius: 10px;
  background: var(--bg-deep);
  object-fit: cover;
  transition: transform var(--d-base) var(--e-out);
}
.pair:hover .pair-thumb { transform: scale(1.04); }

.pair-text { display: grid; gap: 7px; min-width: 0; }

.pair-name {
  font-size: var(--t-fine);
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pair:hover .pair-name, .pair.is-active .pair-name { color: var(--ink); }

.pair-dots { display: flex; }
.pair-dots i {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background-size: cover;
  box-shadow: 0 0 0 1.5px var(--panel-2);
}
.pair-dots i + i { margin-left: -3px; }

/* --- Segmented control ---------------------------------------------------- */

.pills {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: var(--panel-2);
  border: 1px solid var(--line-hair);
  border-radius: var(--r-md);
}

.pill {
  flex: 1;
  font-size: var(--t-fine);
  color: var(--ink-soft);
  border-radius: 10px;
  padding: 10px 12px;
  transition: background var(--d-fast) var(--e-out),
              color var(--d-fast) var(--e-out),
              box-shadow var(--d-fast) var(--e-out);
}
.pill:hover { color: var(--ink); }
.pill.is-active {
  background: var(--ink);
  color: var(--panel);
  box-shadow: var(--shadow-sm);
}

/* --- Checkbox ------------------------------------------------------------- */

.check {
  display: flex;
  align-items: center;
  gap: 13px;
  cursor: pointer;
  user-select: none;
  padding: 12px 14px;
  background: var(--panel-2);
  border: 1px solid var(--line-hair);
  border-radius: var(--r-md);
  transition: border-color var(--d-fast) var(--e-out);
}
.check:hover { border-color: var(--line); }

.check input { position: absolute; opacity: 0; width: 0; height: 0; }

.check-box {
  flex: none;
  width: 21px;
  height: 21px;
  border: 1.5px solid var(--line);
  border-radius: 7px;
  background: var(--panel);
  position: relative;
  transition: background var(--d-fast) var(--e-out), border-color var(--d-fast) var(--e-out);
}
.check-box::after {
  content: "";
  position: absolute;
  left: 6px; top: 2.5px;
  width: 5px; height: 10px;
  border: solid var(--panel);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0.4);
  opacity: 0;
  transition: opacity .16s var(--e-out), transform .16s var(--e-out);
}
.check input:checked + .check-box { background: var(--ink); border-color: var(--ink); }
.check input:checked + .check-box::after { opacity: 1; transform: rotate(45deg) scale(1); }
.check input:focus-visible + .check-box { outline: 2px solid var(--accent); outline-offset: 2px; }

.check-text { font-size: var(--t-small); }
.check-price {
  margin-left: auto;
  font-family: var(--f-mono);
  font-size: var(--t-label);
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.pillow-options {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--line-hair);
}
.pillow-options .group-head { margin-bottom: 13px; }

/* --- Foot ----------------------------------------------------------------- */

.panel-foot {
  padding: 22px 32px 28px;
  border-top: 1px solid var(--line-soft);
  background: var(--panel);
}

.price {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  column-gap: 12px;
  margin-bottom: 18px;
}
.price-label {
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.price strong {
  justify-self: end;
  font-family: var(--f-display);
  font-size: var(--t-price);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1;
  font-variant-numeric: tabular-nums;   /* the number must not jitter */
  white-space: nowrap;
}
.price-note {
  grid-column: 1 / -1;
  margin-top: 7px;
  font-size: var(--t-fine);
  color: var(--muted);
}

.cta {
  width: 100%;
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--panel);
  background: var(--ink);
  border-radius: var(--r-md);
  padding: 16px;
  box-shadow: 0 1px 2px rgba(25, 20, 16, 0.2), 0 12px 26px -14px rgba(25, 20, 16, 0.7);
  transition: background var(--d-fast) var(--e-out),
              transform var(--d-fast) var(--e-out),
              box-shadow var(--d-fast) var(--e-out);
}
.cta:hover {
  background: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 1px 2px rgba(168, 85, 31, 0.3), 0 16px 32px -14px rgba(168, 85, 31, 0.8);
}
.cta:active { transform: translateY(0); }

/* add to cart, and beside it the heart that keeps the design */
.cta-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; }
.fav-btn {
  display: grid;
  place-items: center;
  width: 52px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--ink);
  transition: border-color var(--d-fast) var(--e-out), background var(--d-fast) var(--e-out), color var(--d-fast) var(--e-out);
}
.fav-btn:hover { border-color: var(--ink); }
.fav-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; transition: fill var(--d-fast) var(--e-out), transform 360ms var(--e-out); }
.fav-btn[aria-pressed="true"] { color: var(--accent); border-color: var(--accent); }
.fav-btn[aria-pressed="true"] svg { fill: currentColor; transform: scale(1.06); }

/* --- Three pieces ----------------------------------------------------------
   The armchair, the sofa and the coffee table, the first thing in the sheet: a
   drawing of each over its name. The chosen one is the ink block, the others
   the paper. */

.products {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-bottom: 24px;
}
.product {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 10px 6px 9px;
  border: 1px solid var(--line-hair);
  border-radius: var(--r-md);
  background: var(--panel-2);
  color: var(--ink-soft);
  font-size: var(--t-small);
  line-height: 1.2;
  text-align: center;
  transition: background var(--d-fast) var(--e-out), color var(--d-fast) var(--e-out),
              border-color var(--d-fast) var(--e-out), box-shadow var(--d-fast) var(--e-out);
}
.product svg {
  flex: none;
  width: 40px; height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.35;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.product:hover { color: var(--ink); border-color: var(--line); }
.product.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--panel);
  box-shadow: var(--shadow-sm);
}

/* the shapes, each with its plan or its front drawn in a line */
.pills--icons .pill {
  display: grid;
  justify-items: center;
  gap: 5px;
  padding: 10px 6px 9px;
}
.pills--icons .pill svg {
  width: 30px; height: 26px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- Cloth tabs ------------------------------------------------------------
   Boucle, velvet, linen: words over the tones of the open one. The chosen
   cloth's tab keeps a copper dot when another tab is open, so a visitor who
   browses the velvets still knows which cloth the sofa wears. */

.ftabs {
  display: flex;
  gap: 22px;
  margin: -4px 0 15px;
  border-bottom: 1px solid var(--line-hair);
}
.ftabs[hidden] { display: none; }
.ftab {
  position: relative;
  padding: 6px 0 10px;
  font-size: var(--t-fine);
  color: var(--muted);
  transition: color var(--d-fast) var(--e-out);
}
.ftab:hover { color: var(--ink); }
.ftab.is-active { color: var(--ink); }
.ftab::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1.5px;
  background: var(--ink);
  transform: scaleX(0);
  transition: transform var(--d-base) var(--e-out);
}
.ftab.is-active::after { transform: scaleX(1); }
.ftab.has-pick:not(.is-active)::before {
  content: "";
  position: absolute;
  top: 6px; right: -8px;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

/* eight tones to a row (the sofa's cloths), the tooltips leaning in at the ends */
.swatches--8 { grid-template-columns: repeat(8, minmax(0, 38px)); gap: 8px; }
.swatches--8 .swatch::after { left: 50%; right: auto; transform: translateX(-50%); }
.swatches--8 .swatch:nth-child(8n + 1)::after { left: 0; transform: none; }
.swatches--8 .swatch:nth-child(8n)::after { left: auto; right: 0; transform: none; }

.group-side { display: inline-flex; align-items: center; gap: 12px; min-width: 0; }
.group-side .group-value { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* "close-up": a small quiet button beside the fabric's name */
.look {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-pill);
  font-size: var(--t-label);
  font-family: var(--f-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  transition: color var(--d-fast) var(--e-out), border-color var(--d-fast) var(--e-out), background var(--d-fast) var(--e-out);
}
.look:hover { color: var(--ink); border-color: var(--line); background: var(--panel-2); }
.look svg {
  width: 14px; height: 14px;
  fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round;
}

/* --- Tools: round, named on hover ------------------------------------------
   Five of them now (dimensions, compare, share, snapshot, reset): as pills
   with words they ran into the dimension chip; as drawn icons in a row they
   read as one instrument, and each says its name when the pointer reaches it. */

.tool {
  position: relative;
  width: 42px; height: 42px;
  padding: 0;
  justify-content: center;
  border-radius: 50%;
}
.tool span {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.tool svg { width: 17px; height: 17px; }
.tool::after {
  content: attr(data-name);
  position: absolute;
  right: 50%;
  bottom: calc(100% + 10px);
  transform: translateX(50%);
  padding: 4px 9px;
  border-radius: var(--r-sm);
  background: var(--ink);
  color: var(--panel);
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: 0.05em;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--d-fast) var(--e-out);
}
.tool:last-child::after { right: 0; transform: none; }
.tool:hover::after, .tool:focus-visible::after { opacity: 1; }
.tool.is-on { background: var(--ink); color: var(--panel); border-color: var(--ink); }
.tool__badge {
  position: absolute;
  top: -3px; right: -3px;
  display: grid;
  place-items: center;
  width: 17px; height: 17px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-family: var(--f-mono);
  font-size: 9px;
  font-style: normal;
  font-weight: 600;
  box-shadow: 0 0 0 2px var(--panel);
  transform: scale(0);
  transition: transform var(--d-base) var(--e-out);
}
.tool.has-a .tool__badge { transform: scale(1); }

/* --- Sheets: the close-up and the comparison -------------------------------
   A card over a dimmed, softened page: Escape, the cross or the backdrop
   closes it. It rises a few pixels as it fades in. */

.sheet {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(25, 20, 16, 0.4);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  transition: opacity 360ms var(--e-out);
}
.sheet[hidden] { display: none; }
.sheet.is-open { opacity: 1; }
.sheet__card {
  position: relative;
  width: 100%;
  max-height: calc(100vh - 48px);
  overflow: auto;
  background: var(--panel);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg), 0 40px 90px -40px rgba(25, 20, 16, 0.6);
  transform: translateY(16px) scale(0.985);
  transition: transform 520ms var(--e-out);
}
.sheet.is-open .sheet__card { transform: none; }
.sheet__close {
  position: absolute;
  top: 14px; right: 14px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: rgba(253, 251, 247, 0.92);
  box-shadow: var(--shadow-sm);
  transition: transform var(--d-fast) var(--e-out);
}
.sheet__close:hover { transform: rotate(90deg); }
.sheet__close svg { width: 16px; height: 16px; fill: none; stroke: var(--ink); stroke-width: 1.6; stroke-linecap: round; }

.sheet__card--look {
  max-width: 1060px;
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
}
.look-pic {
  position: relative;
  margin: 0;
  aspect-ratio: 14 / 9;
  background: var(--bg-deep);
  overflow: hidden;
}
.look-pic img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 420ms var(--e-out);
}
#closeup-img.is-in { opacity: 1; }
#closeup-img2.is-on { opacity: 1; }
.look-text {
  display: grid;
  align-content: center;
  gap: 10px;
  padding: 40px 34px 34px;
}
.look-text h2 {
  font-family: var(--f-display);
  font-size: clamp(1.7rem, 2.2vw, 2.2rem);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.look-desc { font-size: var(--t-small); line-height: 1.65; color: var(--ink-soft); max-width: 34ch; }
.look-label {
  margin-top: 16px;
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.swatches--tones { display: flex; flex-wrap: wrap; gap: 9px; }
.swatches--tones .swatch { width: 36px; }
.swatches--tones .swatch::after { display: none; }

.sheet__card--compare { max-width: 1120px; padding: 30px 32px 28px; }
.cmp-head { display: grid; gap: 10px; margin-bottom: 22px; padding-right: 48px; }
.cmp-head h2 {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 2vw, 1.95rem);
  font-weight: 400;
  letter-spacing: -0.02em;
}
.cmp-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
.cmp { margin: 0; }
.cmp-pic {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--bg-deep);
  aspect-ratio: 4 / 3;
}
.cmp-pic canvas { display: block; width: 100%; height: 100%; object-fit: cover; }
.cmp-tag {
  position: absolute;
  top: 12px; left: 12px;
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: rgba(253, 251, 247, 0.92);
  font-family: var(--f-mono);
  font-size: var(--t-label);
  box-shadow: var(--shadow-sm);
}
.cmp figcaption { display: grid; gap: 4px; margin-top: 14px; }
.cmp-label {
  font-family: var(--f-mono);
  font-size: var(--t-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.cmp-name { font-family: var(--f-display); font-size: 1.3rem; }
.cmp-spec { font-size: var(--t-fine); color: var(--ink-soft); line-height: 1.5; }
.cmp-price { font-family: var(--f-display); font-size: 1.55rem; font-weight: 400; font-variant-numeric: tabular-nums; }
.cmp-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
}
.cmp-diff { font-size: var(--t-small); color: var(--ink-soft); }
.cmp-actions { display: flex; gap: 10px; }
.btn-line, .btn-solid {
  font-size: var(--t-fine);
  font-weight: 500;
  padding: 12px 18px;
  border-radius: var(--r-md);
  transition: background var(--d-fast) var(--e-out), color var(--d-fast) var(--e-out), border-color var(--d-fast) var(--e-out);
}
.btn-line { border: 1px solid var(--line); color: var(--ink); }
.btn-line:hover { border-color: var(--ink); }
.btn-solid { background: var(--ink); color: var(--panel); }
.btn-solid:hover { background: var(--accent); }

/* --- Narrow --------------------------------------------------------------- */

@media (max-width: 900px) {
  .app {
    grid-template-columns: 1fr;
    grid-template-rows: 46vh auto;
    height: auto;
    min-height: 0;
  }

  .panel { border-left: 0; border-top: 1px solid var(--line-soft); box-shadow: none; }
  .panel-head { padding: 22px 20px 16px; }
  .panel-body { padding: 4px 20px 18px; overflow: visible; mask-image: none; }
  .panel-foot { padding: 18px 20px 24px; position: sticky; bottom: 0; }
  .group { padding: 18px 0; }

  .stage-top, .stage-bottom { inset-inline: 16px; }
  .stage-top { top: 16px; }
  .hint { display: none; }
  /* The chair fills the stage on a phone: the measurements go up under the mark
     and the two tools become round icons in the corner, clear of the legs
     (they used to sit over them). The words stay for screen readers. */
  .stage-bottom { position: static; }
  .stage-bottom__left { position: absolute; z-index: 2; top: 14px; right: 16px; justify-items: end; }
  .tools { position: absolute; z-index: 2; right: 14px; bottom: 14px; }
  .tools { gap: 6px; }
  .tool { width: 40px; height: 40px; }
  .tool::after { display: none; }
  .products { margin-bottom: 18px; }
  .sheet { padding: 12px; align-items: end; }
  .sheet__card { max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); }
  .sheet__card--look { grid-template-columns: 1fr; }
  .look-text { padding: 22px 20px 24px; }
  .sheet__card--compare { padding: 22px 18px 20px; }
  .cmp-grid { grid-template-columns: 1fr; gap: 16px; }
  .cmp-foot { flex-direction: column; align-items: stretch; }
  .cmp-actions { flex-direction: column-reverse; }

  .swatches { gap: 10px; grid-template-columns: repeat(6, minmax(0, 40px)); }
  .swatches--4 { grid-template-columns: repeat(4, minmax(0, 40px)); }
  .swatches--8 { grid-template-columns: repeat(8, minmax(0, 34px)); gap: 7px; }
  /* A tooltip that needs hover is dead weight on a touch screen, and it
     covers the swatch above it. */
  .swatch::after { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .stage canvas, .hint { opacity: 1; }
}

/* The dimension chip and the drag prompt share the bottom-left corner: one
   states a fact about the product, the other tells you what you can do to
   it. Stacked, not side by side, so neither is mistaken for the other. */
.stage-bottom__left { display: grid; gap: 10px; justify-items: start; }



/* --- Waiting for the next piece ----------------------------------------------
   While the stage still shows the last piece (or dress) and the next one's
   frames are on their way, a thin line moves along the stage's foot. It
   appears only if the wait outlasts a blink. */
.stage-load {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: 0;
  width: min(220px, 40%);
  height: 2px;
  transform: translateX(-50%);
  overflow: hidden;
  border-radius: 2px;
  background: rgba(25, 20, 16, 0.08);
  opacity: 0;
  pointer-events: none;
  transition: opacity 240ms var(--e-out);
}
.stage-load::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 40%;
  background: var(--ink);
  opacity: 0.5;
  animation: stage-load 1.1s ease-in-out infinite;
  animation-play-state: paused;
}
.stage.is-loading .stage-load { opacity: 1; transition-delay: 280ms; }
.stage.is-loading .stage-load::after { animation-play-state: running; }
@keyframes stage-load { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
