/* ==========================================================================
   Style Lab — ehyong.com/style-lab
   Built on the site's own tokens from style.css. Loads after it.

   Layout logic:
     desktop ≥1080px  →  sticky hero left, scrolling style rail right
     tablet  ≥720px   →  hero on top, 3-up style grid below
     mobile           →  hero on top, 2-up grid, sticky action bar at the foot

   The hero is the only thing that ever moves. Everything else stays put so
   the eye has one place to look while the visitor clicks through 52 styles.
   ========================================================================== */

.sl {
  --sl-gap: clamp(16px, 2.2vw, 28px);
  --sl-rail: 400px;
}

/* ------------------------------------------------------------------ intro */

/* .sl-hero-copy is applied TO .container, and .container is
   `width: min(1180px, 100%-48px); margin-inline: auto`. Putting a narrower
   max-width on it re-centres the whole block, so the heading no longer lines
   up with every other section on the site. Constrain the child instead. */
.sl-hero-copy h1 { margin: 0 0 14px; max-width: 20ch; }
.sl-lede { margin: 0; max-width: 62ch; color: var(--text-dim); font-size: clamp(15px, 1.7vw, 18px); }

.sl-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  margin-top: 22px;
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.sl-meta b { color: var(--gold); font-weight: 600; }
:lang(zh) .sl-meta { letter-spacing: .04em; text-transform: none; font-size: 13px; }

/* ------------------------------------------------------------------ shell */

.sl-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--sl-rail);
  gap: var(--sl-gap);
  align-items: start;
}

/* ------------------------------------------------------------------- stage */

.sl-stage { position: sticky; top: calc(var(--header-h, 78px) + 16px); }

.sl-frame {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  background: #0b0b0b;
  border: 1px solid var(--line-soft);
  aspect-ratio: 3 / 4;
  /* The stage is sticky, so it must fit the viewport with the header and the
     button row still visible — otherwise the controls sit below the fold and
     the whole sticky idea stops working. */
  max-height: calc(100vh - var(--header-h, 78px) - 130px);
  box-shadow: var(--shadow-md);
}

.sl-canvas {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.sl-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: filter .5s ease, opacity .35s ease, transform .5s ease;
  will-change: filter;
}

/* Pixel-art styles need nearest-neighbour scaling, not smoothing. */
.sl-canvas.is-pixel .sl-img {
  image-rendering: pixelated;
  transform: scale(1.004);
}

.sl-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transition: opacity .5s ease, background .5s ease;
}

/* Loading + empty states -------------------------------------------------- */

.sl-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 55%, rgba(0, 0, 0, .78));
  pointer-events: none;
}

.sl-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: 22px clamp(16px, 2.4vw, 26px);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px;
}

.sl-caption-name { margin: 0; font-size: clamp(19px, 2.4vw, 26px); line-height: 1.2; }
.sl-caption-era { margin: 5px 0 0; font-size: 12px; color: var(--gold); letter-spacing: .08em; }
:lang(zh) .sl-caption-era { letter-spacing: .02em; }

.sl-badge {
  flex: none;
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 3px;
  border: 1px solid currentColor;
  white-space: nowrap;
}

.sl-badge.is-real { color: #7fae86; background: rgba(127, 174, 134, .12); }
.sl-badge.is-preview { color: var(--text-muted); border-style: dashed; }
:lang(zh) .sl-badge { letter-spacing: .02em; text-transform: none; font-size: 11px; }

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

.sl-stage-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}

.sl-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color .2s ease, background .2s ease, color .2s ease;
}

/* .sl-btn sets display:inline-flex, which out-ranks the [hidden] UA rule. */
.sl-btn[hidden], [hidden] { display: none !important; }

.sl-btn:hover { border-color: var(--gold); color: var(--gold); }
.sl-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.sl-btn[aria-pressed="true"] { background: var(--gold); border-color: var(--gold); color: #100c04; }

.sl-btn--primary {
  background: var(--gold);
  border-color: var(--gold);
  color: #100c04;
  font-weight: 600;
}

.sl-btn--primary:hover { background: var(--gold-soft); border-color: var(--gold-soft); color: #100c04; }


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

.sl-rail { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.sl-search-row { display: flex; gap: 8px; }

.sl-search {
  flex: 1;
  min-width: 0;
  padding: 12px 15px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-soft);
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: 14px;
}

.sl-search::placeholder { color: var(--text-muted); }
.sl-search:focus { outline: none; border-color: var(--gold); }

.sl-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.sl-chip {
  padding: 7px 13px;
  border-radius: 999px;
  border: 1px solid var(--line-soft);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  transition: border-color .2s ease, color .2s ease, background .2s ease;
}

.sl-chip:hover { color: var(--text); border-color: var(--line); }
.sl-chip[aria-pressed="true"] { background: var(--gold-faint); border-color: var(--gold); color: var(--gold); }
.sl-chip:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.sl-count { font-size: 12px; color: var(--text-muted); }

/* Style grid -------------------------------------------------------------- */

.sl-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  max-height: min(64vh, 680px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: 6px;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.sl-grid::-webkit-scrollbar { width: 8px; }
.sl-grid::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }

.sl-tile {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  background: var(--panel);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  transition: border-color .2s ease, transform .2s ease;
}

.sl-tile:hover { border-color: var(--line); transform: translateY(-2px); }
.sl-tile:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.sl-tile[aria-pressed="true"] { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold) inset; }

@media (prefers-reduced-motion: reduce) { .sl-tile:hover { transform: none; } }

.sl-swatch {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: #0b0b0b;
}

/* The swatch is 4:3 but every render is 3:4, so `cover` crops top and bottom.
   Centring lands on the chest — which turns Film Noir and Technicolor into
   black rectangles. Bias the crop upward to keep the face in every thumbnail. */
.sl-swatch img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 22%;
  display: block;
}
.sl-swatch .sl-overlay { transition: none; }

.sl-tile-label {
  display: block;
  padding: 9px 11px 11px;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
}

.sl-tile-label small {
  display: block;
  margin-top: 3px;
  font-size: 10.5px;
  font-weight: 400;
  color: var(--text-muted);
  letter-spacing: .04em;
}

.sl-tile[aria-pressed="true"] .sl-tile-label { color: var(--gold); }

.sl-empty { padding: 26px 4px; color: var(--text-muted); font-size: 14px; }

/* ------------------------------------------------------------------ detail */

.sl-detail {
  margin-top: clamp(28px, 4vw, 52px);
  border-top: 1px solid var(--line-soft);
  padding-top: clamp(24px, 3.5vw, 40px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(22px, 3vw, 46px);
  align-items: start;
}

.sl-detail h2 { margin: 0 0 6px; font-size: clamp(22px, 2.8vw, 32px); }
.sl-detail-zh { margin: 0 0 16px; color: var(--gold); font-size: 15px; }

.sl-facts { margin: 0 0 18px; padding: 0; list-style: none; display: grid; gap: 9px; }

.sl-facts div {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  gap: 12px;
  font-size: 14px;
}

.sl-facts dt {
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding-top: 3px;
}

:lang(zh) .sl-facts dt { letter-spacing: .03em; text-transform: none; font-size: 12px; }
.sl-facts dd { margin: 0; color: var(--text); }

.sl-intro {
  margin: 0;
  padding: 15px 18px;
  border-left: 2px solid var(--gold-faint);
  background: rgba(214, 174, 103, .05);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--text);
  font-size: 15px;
}

/* Prompt box -------------------------------------------------------------- */

.sl-prompt-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.sl-prompt-head h3 {
  margin: 0;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gold);
}

:lang(zh) .sl-prompt-head h3 { letter-spacing: .04em; text-transform: none; font-size: 13px; }

.sl-prompt {
  margin: 0;
  padding: 18px 20px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-sm);
  background: var(--panel);
  color: var(--text-dim);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.65;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 320px;
  overflow-y: auto;
}

.sl-copy-note { margin: 10px 0 0; font-size: 12px; color: var(--text-muted); }

/* ------------------------------------------------------------- how it works */

.sl-steps {
  list-style: none;
  counter-reset: sl;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}

.sl-steps li {
  counter-increment: sl;
  padding: 22px 20px;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  background: var(--bg-lift);
}

.sl-steps li::before {
  content: counter(sl);
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  margin-bottom: 12px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  color: var(--gold);
  font-size: 13px;
  font-weight: 600;
}

.sl-steps h3 { margin: 0 0 6px; font-size: 16px; }
.sl-steps p { margin: 0; font-size: 14px; color: var(--text-dim); }

/* --------------------------------------------------------------- responsive */

@media (max-width: 1079px) {
  .sl-shell { grid-template-columns: 1fr; }
  .sl-stage { position: static; }
  .sl-frame { aspect-ratio: 4 / 3; max-height: 62vh; }
  .sl-grid { grid-template-columns: repeat(3, 1fr); max-height: none; overflow: visible; padding-right: 0; }
  .sl-detail { grid-template-columns: 1fr; }
  .sl-steps { grid-template-columns: 1fr; }
}

@media (max-width: 700px) {
  .sl-frame { aspect-ratio: 3 / 4; max-height: 58vh; }
  .sl-grid { grid-template-columns: repeat(2, 1fr); }
  .sl-facts div { grid-template-columns: 1fr; gap: 2px; }
  .sl-facts dt { padding-top: 0; }
  .sl-caption { padding: 16px; }
  .sl-prompt { font-size: 12.5px; padding: 14px 15px; }
  .sl-btn { flex: 1 1 auto; justify-content: center; }
}

/* ---------------------------------------------------------------- support */

/* The coffee ask sits at the TOP of the picker rail, not at the foot of the
   page — it is the first thing beside the portrait, and it stays put while
   the style grid scrolls under it. Written as a quiet panel rather than a
   yellow banner: it now sits ABOVE the tool, so it has to be readable
   without competing with the thing the visitor came for. Only the button
   carries Buy Me a Coffee's yellow, and only at button size. */

.sl-support {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: linear-gradient(180deg, rgba(214, 174, 103, .07), rgba(214, 174, 103, 0));
  padding: 18px;
}

.sl-support-h {
  margin: 0 0 8px;
  font-size: 17px;
  line-height: 1.25;
  color: var(--text);
}

:lang(zh) .sl-support-h { font-size: 16px; }

.sl-support-p {
  margin: 0 0 16px;
  font-size: 13px;
  line-height: 1.62;
  color: var(--text-dim);
}

.sl-support-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.sl-support-act { min-width: 0; }

.sl-coffee {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 10px 17px;
  border-radius: var(--r-sm);
  background: #ffdd00;
  color: #131313;
  border: 1px solid #ffdd00;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: .01em;
  text-decoration: none;
  white-space: nowrap;
  transition: transform .16s ease, background .16s ease, box-shadow .16s ease;
}

.sl-coffee svg { flex: 0 0 auto; width: 16px; height: 16px; }

.sl-coffee:hover,
.sl-coffee:focus-visible {
  background: #ffe94d;
  border-color: #ffe94d;
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(255, 221, 0, .16);
}

.sl-support-url {
  margin: 9px 0 0;
  font-size: 11.5px;
  letter-spacing: .01em;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* Deliberately small and slightly held back. The QR is the secondary route —
   the button is the action on a desktop, where the pointer is already in
   hand. It brightens to full white on hover or keyboard focus, which is when
   someone is actually reaching for their phone. */
.sl-qr {
  margin: 0;
  flex: 0 0 auto;
  opacity: .72;
  transition: opacity .2s ease;
}

.sl-support:hover .sl-qr,
.sl-qr:focus-within { opacity: 1; }

/* White plate, always. A QR needs a light quiet zone around it to scan; on
   the site's near-black ground the dark modules would bleed into the page
   and phones would hunt for the finder patterns. */
.sl-qr-plate {
  background: #fff;
  border-radius: 7px;
  padding: 5px;
  line-height: 0;
}

.sl-qr-plate img {
  display: block;
  width: 68px;
  height: 68px;
  image-rendering: -webkit-optimize-contrast;  /* keep module edges hard */
}

/* No caption. The URL already sits under the button, and a label under a
   68px code says nothing the code doesn't. The alt text carries it for
   screen readers. */
.sl-qr figcaption { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* 1079px is where .sl-shell collapses to one column — this number must track
   that rule, not be picked independently. Below it the rail is no longer a
   column beside the portrait; it is the tool itself, in one vertical run, so
   the card would land between the picture and the style grid — a payment ask
   dropped into the middle of the interaction. It moves to the end instead,
   where the visitor has already had the thing it is asking about. */
@media (max-width: 1079px) {
  .sl-support { order: 2; }
}

@media (max-width: 600px) {
  .sl-qr { display: none; }
  .sl-support-row { display: block; }
  .sl-coffee { width: 100%; justify-content: center; padding: 13px 17px; }
}

/* The rail's own scroll is a desktop nicety; on mobile the page scrolls. */
@media (hover: none) {
  .sl-grid { -webkit-overflow-scrolling: touch; }
}

/* Print: the prompt is the thing worth printing. */
@media print {
  .sl-rail, .sl-stage-bar, .sl-steps, .site-header, .site-footer, .wa-fab,
  .sl-support { display: none !important; }
  .sl-shell, .sl-detail { grid-template-columns: 1fr; }
  .sl-prompt { max-height: none; border-color: #999; color: #000; background: #fff; }
}

/* ==========================================================================
   Touch targets and a minimum type size

   The style grid is the whole page on a phone: 52 tiles, each with a name and
   an era, and a row of family chips above them. Anything here that is hard to
   hit or hard to read is not a detail — it is the tool.
   ========================================================================== */

@media (hover: none), (max-width: 768px) {

  /* Family chips: 36px tall. They sit in a wrapping row with a 6px gap, so
     the extra height separates rows rather than merging targets. */
  .sl-filters .sl-chip { padding: 12px 15px; font-size: 12.5px; }

  /* The era under each tile name, and the AI render / Live preview badge. */
  .sl-tile .sl-tile-label small { font-size: 11.5px; }
  .sl-caption .sl-badge { font-size: 11.5px; }

  /* Same specificity problem as radar.css: :lang(zh) .sl-badge is 0,2,0. */
  :lang(zh) .sl-caption .sl-badge { font-size: 11.5px; }

  /* Era / Origin / Inventor labels in the detail panel — 10.5px uppercase
     with letter-spacing is the least legible combination on the page. */
  .sl-detail .sl-facts dt { font-size: 12px; }
  .sl-detail .sl-prompt-head h3 { font-size: 12.5px; }
}
