/* ============================================================
   INDUSTRY STANDARDS
   Aesthetic: technical catalog / spec sheet.
   Warm catalog stock, blueprint grid, hairline rules, condensed
   signage type, one safety-orange accent, certification stamps.
   ============================================================ */

:root {
  --paper:      #FFFFFF;
  --paper-hi:   #FFFFFF;
  --paper-lo:   #F0F0F0;
  --ink:        #17160F;
  --ink-2:      #55514550;
  --ink-soft:   #56524A;
  --accent:     #FF8B00;
  --accent-lo:  #FF8B0014;
  --rule:       #17160F26;
  --rule-hard:  #17160F;
  /* The background grid is its own tone: it has to sit well below the
     hairline borders that use --rule, or the page reads as a table. */
  --grid-line:  #17160F0F;

  --grid:       16px;
  --gut:        clamp(1.1rem, 3.2vw, 2.4rem);
  --maxw:       1360px;

  --mono: "Space Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --sans: "Space Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --ease: cubic-bezier(.2, .7, .2, 1);
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  min-height: 100vh;
  /* Keeps the colophon at the bottom of short pages instead of floating
     halfway up the viewport. */
  display: flex; flex-direction: column;
  font-family: var(--sans);
  color: var(--ink);
  background-color: var(--paper);
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: var(--grid) var(--grid);
  background-position: -1px -1px;
  line-height: 1.5;
  overflow-x: hidden;
}

/* Faint blueprint grid should read as texture, not as a table. */
body::before {
  content: "";
  position: fixed; inset: 0;
  background: radial-gradient(120% 90% at 50% 0%, transparent 30%, var(--paper) 100%);
  pointer-events: none; z-index: 0;
}

.grain {
  position: fixed; inset: -50%;
  z-index: 1; pointer-events: none;
  opacity: .32; 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='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--ink); color: var(--paper); padding: .6rem 1rem;
  font: 600 .8rem/1 var(--mono);
}
.skip:focus { left: 0; }

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

/* ---------- shared type ---------- */

h1, h2, h3, h4 { margin: 0; font-weight: 800; letter-spacing: -.01em; }

.eyebrow {
  font: 500 .68rem/1 var(--mono);
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--ink-soft);
}

.num {
  font: 500 .68rem/1 var(--mono);
  letter-spacing: .06em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

a { color: inherit; }

#view { flex: 1 0 auto; position: relative; z-index: 2; }

.wrap {
  position: relative; z-index: 2;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gut);
}

/* ============================================================
   MASTHEAD
   ============================================================ */

.masthead {
  position: sticky; top: 0; z-index: 40;
  background: var(--paper);
  border-bottom: 1.5px solid var(--rule-hard);
  box-shadow: 0 1px 0 var(--rule);
}

.masthead__bar {
  max-width: var(--maxw);
  margin-inline: auto;
  padding: .55rem var(--gut);
  display: flex; align-items: center; gap: 1.5rem;
}

.wordmark {
  display: flex; align-items: center; gap: .6rem;
  text-decoration: none; flex: none;
}
.wordmark__mark {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--accent); flex: none;
  box-shadow: 0 0 0 4px var(--paper), 0 0 0 5px var(--rule-hard);
  transition: transform .5s var(--ease);
}
.wordmark:hover .wordmark__mark { transform: rotate(180deg) scale(1.08); }
.wordmark__text {
  font-weight: 800; font-size: .92rem; line-height: .95;
  text-transform: uppercase; letter-spacing: .01em;
}

.nav {
  margin-left: auto;
  display: flex; align-items: center; gap: 1.35rem;
  font: 500 .72rem/1 var(--mono);
  letter-spacing: .1em; text-transform: uppercase;
}
.nav a { text-decoration: none; color: var(--ink-soft); position: relative; padding: .35rem 0; white-space: nowrap; }
.nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .3s var(--ease);
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--ink); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }

.nav__cta {
  color: var(--paper) !important;
  background: var(--ink);
  padding: .5rem .8rem !important;
}
.nav__cta::after { display: none; }
.nav__cta:hover { background: var(--accent); }

.nav__account { display: flex; align-items: center; gap: .8rem; }
.nav__account button {
  font: 500 .72rem/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  background: none; border: 0; color: var(--ink-soft); cursor: pointer; padding: .35rem 0;
}
.nav__account button:hover { color: var(--accent); }

.nav-toggle { display: none; }

.masthead__ticker {
  border-top: 1px solid var(--rule);
  background: var(--ink);
  color: var(--paper-lo);
  font: 400 .66rem/1 var(--mono);
  letter-spacing: .16em; text-transform: uppercase;
  padding: .42rem 0;
  overflow: hidden; white-space: nowrap;
  max-width: 100%;
}
/* Continuous marquee: the track holds two identical runs, so translating it
   exactly -50% loops without a visible seam. */
.masthead__ticker div {
  display: inline-flex; align-items: center;
  animation: ticker 62s linear infinite;
  will-change: transform;
}
.masthead__ticker:hover div { animation-play-state: paused; }
@keyframes ticker { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .masthead__ticker div { animation: none; }
  .masthead__ticker { padding-inline: var(--gut); text-overflow: ellipsis; }
}
.masthead__ticker span { opacity: .72; }
.masthead__ticker b { color: var(--accent); font-weight: 500; }
.masthead__ticker i { font-style: normal; opacity: .3; padding: 0 .9rem; }

@media (max-width: 900px) {
  .nav {
    position: absolute; top: 100%; left: 0; right: 0;
    background: var(--paper);
    border-bottom: 1.5px solid var(--rule-hard);
    flex-direction: column; align-items: stretch; gap: 0;
    padding: .5rem var(--gut) 1rem;
    display: none;
  }
  .nav.open { display: flex; }
  .nav a { padding: .85rem 0; border-bottom: 1px solid var(--rule); }
  .nav__cta { text-align: center; margin-top: .8rem; }
  .nav__account { padding: .6rem 0; flex-direction: column; align-items: flex-start; }
  .nav-toggle {
    display: flex; flex-direction: column; justify-content: center; gap: 5px;
    margin-left: auto; width: 34px; height: 34px;
    background: none; border: 1px solid var(--rule-hard); cursor: pointer; padding: 0 7px;
  }
  .nav-toggle span { display: block; height: 1.5px; background: var(--ink); transition: transform .3s var(--ease), opacity .2s; }
  .nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
}

/* ============================================================
   HERO / FRONT MATTER
   ============================================================ */

.hero {
  position: relative; z-index: 2;
  max-width: var(--maxw); margin-inline: auto;
  padding: clamp(2.4rem, 7vw, 5rem) var(--gut) clamp(2rem, 5vw, 3.4rem);
}
/* Every other rule on the page is drawn inside the gutter — .industries and
   .catalog carry theirs on the content box, not on the padded container. A
   border on .hero itself would run the full --maxw and overhang all of them by
   a gutter on each side, so this one is inset to match. */
.hero::after {
  content: ""; position: absolute; bottom: 0;
  left: var(--gut); right: var(--gut);
  height: 1.5px; background: var(--rule-hard);
}

/* Compounded with .stamp so it wins over that rule's position: relative,
   which is declared later in this file at equal specificity. */
.stamp.hero__stamp {
  --s: clamp(96px, 15vw, 168px);
  position: absolute;
  right: clamp(1rem, 4vw, 4rem); top: clamp(1.6rem, 5vw, 3.4rem);
  transform: rotate(11deg);
  opacity: .9; pointer-events: none;
  animation: stampIn 1s var(--ease) .5s both;
}
@keyframes stampIn {
  0%   { opacity: 0; transform: rotate(11deg) scale(2.1); }
  60%  { opacity: .95; transform: rotate(11deg) scale(.94); }
  100% { opacity: .9; transform: rotate(11deg) scale(1); }
}

/* One line, always. Space Mono advances .6em per character and the tracking
   pulls .02em back, so the 18-character headline occupies ~10.4em; 8.2vw
   keeps it inside the gutters down to a 320px viewport, and the 7rem ceiling
   holds it inside --maxw once the viewport is wider than the container. */
.hero h1 {
  font-size: clamp(1.5rem, 8.2vw, 7rem);
  line-height: .95;
  text-transform: uppercase;
  letter-spacing: -.02em;
  margin-block: .5rem .8rem;
  white-space: nowrap;
}
/* The lede and the carousel sit side by side under the headline. The second
   track is declared only when a carousel is actually present: heroCarousel()
   returns nothing when too few entries carry an illustration, and a track sized
   for a picture that was never rendered would hold a column of empty space
   beside the lede. The frame has no intrinsic width of its own — it is an
   aspect-ratio box — so the track has to give it one. */
.hero__body {
  display: grid;
  gap: clamp(1.6rem, 4vw, 3.2rem);
  align-items: start;
}
.hero__body:has(.carousel) {
  grid-template-columns: minmax(0, 1fr) clamp(11rem, 24vw, 21rem);
}
.hero__intro { min-width: 0; }

.hero__lede {
  max-width: 46ch;
  font-size: clamp(1.02rem, 1.5vw, 1.22rem);
  line-height: 1.45;
  color: var(--ink-soft);
  margin: 0 0 1.6rem;
}
.hero__lede strong { color: var(--ink); font-weight: 600; }

.hero__stats {
  display: flex; flex-wrap: wrap; gap: 0;
  border-top: 1px solid var(--rule);
  margin-top: 2rem;
}
.hero__stat {
  padding: .9rem 1.6rem .9rem 0;
  margin-right: 1.6rem;
  border-right: 1px solid var(--rule);
}
.hero__stat:last-child { border-right: 0; }
.hero__stat b {
  display: block;
  font-size: clamp(1.6rem, 3.4vw, 2.4rem); font-weight: 800; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.hero__stat span { font: 500 .64rem/1.3 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); }

/* ---- front-page carousel ---- */

.carousel { min-width: 0; }

.carousel__frame {
  position: relative; aspect-ratio: 1;
  border: 1.5px solid var(--rule-hard);
  background: var(--paper-hi);
  overflow: hidden;
}
/* All slides are stacked and dissolved rather than translated: the frame is a
   plate on the page, and a picture that slides draws more attention than the
   headline it sits beside.

   The outgoing slide is held fully opaque underneath while the incoming one
   fades in over it, instead of the two cross-fading. Fading both at once leaves
   the frame half-transparent at the midpoint, and against white paper these
   illustrations are pale enough that the moment reads as an empty box. */
.carousel__slide {
  position: absolute; inset: 0; z-index: 0;
  display: block; text-decoration: none;
  opacity: 0; pointer-events: none;
  transition: opacity .55s var(--ease);
}
.carousel__slide.was-on { opacity: 1; z-index: 1; transition: none; }
.carousel__slide.is-on { opacity: 1; z-index: 2; pointer-events: auto; }
.carousel__slide .thumb { border: 0; height: 100%; }

.carousel__cap {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: .5rem .7rem;
  pointer-events: none;
  background: var(--paper);
  border-top: 1px solid var(--rule);
  font: 500 .62rem/1.35 var(--mono);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.carousel__cap b { color: var(--ink); font-weight: 700; }

.carousel__dots { display: flex; gap: .45rem; margin-top: .75rem; }
.carousel__dot {
  width: .5rem; height: .5rem; padding: 0;
  border: 1.5px solid var(--rule-hard); border-radius: 50%;
  background: transparent; cursor: pointer;
  transition: background .2s var(--ease);
}
.carousel__dot.is-on { background: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .carousel__slide { transition: none; }
}

/* One column on a phone. Source order already puts the lede first, which is the
   thing being read there — the strip follows it instead of pushing it down. */
@media (max-width: 860px) {
  .hero__body:has(.carousel) { grid-template-columns: minmax(0, 1fr); }
  .carousel { width: min(21rem, 100%); }
}

/* ============================================================
   SECTION HEADERS
   ============================================================ */

.section { position: relative; z-index: 2; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gut); }

.section__head {
  display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap;
  padding: clamp(2.2rem, 5vw, 3.6rem) 0 1rem;
}
.section__head h2 {
  font-size: clamp(1.5rem, 3.6vw, 2.5rem);
  text-transform: uppercase; line-height: .95;
}
.section__head p {
  margin: 0; color: var(--ink-soft); font-size: .92rem; max-width: 44ch;
}
.section__head .num { margin-left: auto; }

.rule { height: 1.5px; background: var(--rule-hard); }
.rule--thin { height: 1px; background: var(--rule); }

/* ============================================================
   INDUSTRY INDEX
   ============================================================ */

.industries {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
  border-top: 1.5px solid var(--rule-hard);
  border-left: 1px solid var(--rule);
}
.industry {
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  padding: 1.15rem 1.15rem 1.3rem;
  text-decoration: none;
  display: flex; flex-direction: column; gap: .4rem;
  position: relative; overflow: hidden;
  background: transparent;
  transition: background .25s var(--ease);
}
.industry::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--accent); transform: scaleY(0); transform-origin: top;
  transition: transform .35s var(--ease);
}
.industry:hover { background: var(--paper-hi); }
.industry:hover::before { transform: scaleY(1); }
.industry__top { display: flex; align-items: center; justify-content: space-between; gap: .8rem; }
.industry h3 {
  font-size: 1.14rem; line-height: 1.08; text-transform: uppercase;
}
.industry p { margin: 0; font-size: .82rem; color: var(--ink-soft); line-height: 1.4; }
.industry__count {
  font: 500 .64rem/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); white-space: nowrap;
}
.industry__count b { color: var(--accent); font-weight: 600; }

/* ============================================================
   CATALOG ROWS  (the core listing unit)
   ============================================================ */

.catalog { border-top: 1.5px solid var(--rule-hard); }

.entry {
  display: grid;
  grid-template-columns: 3.2rem 92px minmax(0, 1fr) auto;
  gap: 0 1.3rem;
  align-items: start;
  padding: 1.35rem 0;
  border-bottom: 1px solid var(--rule);
  position: relative;
  text-decoration: none;
  transition: background .2s var(--ease);
}
.entry::before {
  content: ""; position: absolute; left: -.9rem; top: 0; bottom: -1px; width: 3px;
  background: var(--accent); transform: scaleY(0); transform-origin: center;
  transition: transform .3s var(--ease);
}
.entry:hover { background: #17160F06; }
.entry:hover::before { transform: scaleY(1); }

.entry__idx { padding-top: .18rem; }

/* ---------- entry artwork ---------- */

.thumb {
  position: relative;
  aspect-ratio: 1;
  width: 100%;
  border: 1px solid var(--rule);
  background: var(--paper-hi);
  overflow: hidden;
}
.thumb .plate,
.thumb img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
}
.thumb .plate { color: var(--ink); }
/* cover, not contain: the photo fills the square the way the plate does, so a
   row of entries reads as one grid instead of a run of letterboxed boxes. */
.thumb img { object-fit: cover; background: var(--paper-hi); }

.plate__mono {
  font-family: var(--sans);
  font-weight: 800;
  font-size: 40px;
  fill: var(--ink);
  opacity: .45;
  letter-spacing: -.02em;
}

.entry__thumb {
  display: block; text-decoration: none;
  transition: opacity .2s var(--ease);
}
.entry__thumb:hover { opacity: .78; }
.entry:hover .thumb { border-color: var(--rule-hard); }

.detail__figure {
  max-width: 380px;
  margin-bottom: 1.6rem;
}
.detail__figure .thumb { border: 1.5px solid var(--rule-hard); }
.detail__figure .plate__mono { font-size: 34px; }

/* Photo attribution. Sits directly under the figure, deliberately quiet — it is
   a licence obligation, not part of the entry's argument. */
.detail__credit {
  max-width: 380px;
  margin: -1.2rem 0 1.6rem;
  font-size: .68rem;
  line-height: 1.45;
  letter-spacing: .01em;
  color: var(--ink-soft);
}
.detail__credit a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.detail__credit a:hover { color: var(--ink); }

/* Brand runs inline with the product name, at the same size and colour, with
   a hairline rule as the only separation. */
.entry__brand {
  font: inherit;
  color: var(--ink);
  border-right: 1.5px solid var(--rule);
  padding-right: .42em;
  margin-right: .42em;
}
.entry__name {
  font-size: clamp(1.14rem, 2.1vw, 1.42rem); font-weight: 700;
  line-height: 1.12; letter-spacing: -.005em;
  margin: 0 0 .42rem;
}
.entry a.entry__name-link { text-decoration: none; }
.entry a.entry__name-link:hover .entry__name,
.entry a.entry__name-link:hover .entry__brand { color: var(--accent); }
.entry__claim {
  margin: 0; font-size: .89rem; line-height: 1.5; color: var(--ink-soft);
  max-width: 72ch;
}
.entry__meta {
  display: flex; flex-wrap: wrap; gap: .5rem .9rem; align-items: center;
  margin-top: .6rem;
}

.tag {
  font: 500 .6rem/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  border: 1px solid var(--rule); padding: .32rem .5rem; color: var(--ink-soft);
  text-decoration: none;
}
a.tag:hover { border-color: var(--rule-hard); color: var(--ink); }
.tag--std { border-color: var(--accent); color: var(--accent); background: var(--accent-lo); }
.tag--founding { border-style: dashed; }

/* ---------- vote module ---------- */

.vote {
  display: flex; flex-direction: column; align-items: stretch;
  border: 1.5px solid var(--rule-hard);
  width: 62px; flex: none;
  background: var(--paper-hi);
  user-select: none;
}
.vote__btn {
  appearance: none; background: none; border: 0; cursor: pointer;
  padding: .4rem 0; display: grid; place-items: center;
  color: var(--ink-soft);
  transition: background .12s var(--ease), color .12s var(--ease);
}
.vote__btn svg { width: 15px; height: 15px; display: block; }
.vote__btn:hover:not(:disabled) { background: var(--ink); color: var(--paper); }
.vote__btn:active:not(:disabled) { transform: translateY(1px); }
.vote__btn:disabled { cursor: not-allowed; opacity: .45; }
.vote__btn[aria-pressed="true"] { background: var(--accent); color: #fff; }
.vote__score {
  font: 600 1.05rem/1 var(--mono);
  font-variant-numeric: tabular-nums;
  text-align: center; padding: .42rem 0;
  border-block: 1.5px solid var(--rule-hard);
  background: var(--paper);
}
.vote__score.bump { animation: bump .32s var(--ease); }
@keyframes bump { 0%,100% { transform: none; } 40% { transform: scale(1.24); } }

.vote-wrap { display: flex; flex-direction: column; align-items: center; gap: .45rem; }

.meter {
  width: 62px; height: 4px; background: var(--paper-lo);
  border: 1px solid var(--rule); position: relative; overflow: hidden;
}
.meter i { position: absolute; inset: 0 auto 0 0; background: var(--accent); transition: width .6s var(--ease); }
.meter--full i { background: var(--ink); }
.vote-wrap small { font: 500 .56rem/1 var(--mono); letter-spacing: .08em; color: var(--ink-soft); text-transform: uppercase; }

/* ---------- certification stamp ---------- */

.stamp {
  --s: 92px;
  width: var(--s); height: var(--s);
  border: 2.5px solid var(--accent);
  border-radius: 50%;
  display: grid; place-items: center; text-align: center;
  color: var(--accent);
  transform: rotate(-9deg);
  flex: none;
  position: relative;
  opacity: .92;
}
.stamp::after {
  content: ""; position: absolute; inset: 4px; border: 1px solid currentColor; border-radius: 50%;
}
.stamp span {
  font-weight: 800; text-transform: uppercase;
  font-size: calc(var(--s) * .155); line-height: .96; letter-spacing: .01em;
  padding: 0 8%;
}
.stamp small {
  display: block; font: 500 calc(var(--s) * .085)/1.4 var(--mono);
  letter-spacing: .1em; opacity: .8; margin-top: .28em;
}

/* ============================================================
   PRODUCT DETAIL
   ============================================================ */

.detail { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: clamp(1.6rem, 4vw, 3.4rem); padding-block: clamp(1.6rem, 4vw, 2.8rem) 3rem; }
@media (max-width: 860px) { .detail { grid-template-columns: 1fr; } }

.detail__brand {
  font: inherit;
  color: var(--ink);
  border-right: 2px solid var(--rule);
  padding-right: .3em;
  margin-right: .3em;
}
.detail h1 {
  font-size: clamp(2rem, 6vw, 4rem); line-height: .94; text-transform: uppercase;
  margin: .5rem 0 1rem;
}
.detail__claim { font-size: clamp(1.02rem, 1.6vw, 1.2rem); line-height: 1.55; max-width: 62ch; color: var(--ink); margin: 0 0 1.6rem; }

.specs { border-top: 1.5px solid var(--rule-hard); margin-top: 1.4rem; }
.specs div {
  display: grid; grid-template-columns: 11rem minmax(0,1fr);
  gap: 1rem; padding: .72rem 0; border-bottom: 1px solid var(--rule);
  font-size: .9rem;
}
.specs dt { font: 500 .64rem/1.6 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); margin: 0; }
.specs dd { margin: 0; }
.specs a { color: var(--accent); }

.aside__box { border: 1.5px solid var(--rule-hard); padding: 1.2rem; background: var(--paper-hi); margin-bottom: 1.2rem; }
.aside__box h4 { text-transform: uppercase; font-size: .95rem; margin-bottom: .7rem; }
.aside__box p { margin: 0 0 .8rem; font-size: .84rem; color: var(--ink-soft); line-height: 1.5; }
.aside__box .vote-wrap { align-items: stretch; }
.aside__box .vote, .aside__box .meter { width: 100%; }
.aside__box .vote { flex-direction: row; align-items: stretch; }
.aside__box .vote .vote__score { flex: 1; border-block: 0; border-inline: 1.5px solid var(--rule-hard); display: grid; place-items: center; }
.aside__box .vote__btn { flex: none; width: 46px; }

/* ============================================================
   DISCUSSION
   ============================================================ */

.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.thread {
  border-top: 1.5px solid var(--rule-hard);
  padding-top: 2.2rem;
  margin-bottom: 3.5rem;
  max-width: 74ch;
}

.comment {
  border-bottom: 1px solid var(--rule);
  padding: 1.05rem 0;
}
.comment:first-child { border-top: 1px solid var(--rule); }

.comment__meta {
  display: flex; align-items: center; gap: .85rem; flex-wrap: wrap;
  font: 500 .66rem/1 var(--mono);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: .5rem;
}
.comment__meta b { color: var(--ink); font-weight: 600; }
.comment__edited { font-style: italic; opacity: .7; text-transform: none; letter-spacing: .04em; }

.comment__actions {
  margin-left: auto; display: flex; gap: .8rem;
  opacity: 0; transition: opacity .2s var(--ease);
}
.comment:hover .comment__actions,
.comment:focus-within .comment__actions { opacity: 1; }
.comment__actions button {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: 500 .66rem/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft);
}
.comment__actions button:hover { color: var(--accent); }

.comment__body {
  margin: 0; font-size: .95rem; line-height: 1.6;
  overflow-wrap: anywhere;
}

.thread__empty, .thread__signin {
  font-size: .9rem; color: var(--ink-soft);
  padding: 1.2rem 0; margin: 0;
  border-block: 1px solid var(--rule);
}
.thread__signin a { color: var(--accent); }

.composer { margin-top: 1.4rem; }
.composer textarea {
  width: 100%; min-height: 96px; resize: vertical;
  font-family: var(--sans); font-size: .95rem; line-height: 1.55; color: var(--ink);
  background: var(--paper-hi);
  border: 1.5px solid var(--rule-hard); border-radius: 0;
  padding: .8rem .85rem;
  transition: box-shadow .2s;
}
.composer textarea:focus { outline: 0; box-shadow: 3px 3px 0 var(--accent); }
.composer__row {
  display: flex; align-items: center; justify-content: flex-end;
  gap: .8rem; margin-top: .7rem;
}
.composer__row .hint {
  margin-right: auto; font: 400 .74rem/1.4 var(--mono); color: var(--accent);
}
.composer--inline { margin-top: .2rem; }

/* ============================================================
   FORMS
   ============================================================ */

.form { max-width: 640px; padding-block: clamp(1.6rem, 4vw, 2.6rem) 4rem; }
.field { margin-bottom: 1.35rem; }
.field label {
  display: block; font: 500 .64rem/1 var(--mono); letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-soft); margin-bottom: .5rem;
}
.field input, .field textarea, .field select {
  width: 100%; font-family: var(--sans); font-size: 1rem; color: var(--ink);
  background: var(--paper-hi);
  border: 1.5px solid var(--rule-hard); border-radius: 0;
  padding: .78rem .85rem;
  transition: border-color .2s, box-shadow .2s;
}
.field select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%), linear-gradient(135deg, var(--ink) 50%, transparent 50%); background-position: calc(100% - 18px) 55%, calc(100% - 13px) 55%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 2.4rem; }
.field textarea { min-height: 130px; resize: vertical; line-height: 1.5; }
.field input:focus, .field textarea:focus, .field select:focus { outline: 0; box-shadow: 3px 3px 0 var(--accent); }
.field .hint { font: 400 .74rem/1.45 var(--mono); color: var(--ink-soft); margin-top: .45rem; }
.field .count { float: right; font-variant-numeric: tabular-nums; }
.field .hint a { color: var(--accent); }

/* The reference link is step one of the submit form, not the last optional box
   on it, so it is drawn as its own panel above the fields it fills. */
.field--lead {
  border: 1.5px solid var(--rule-hard); border-left-width: 5px; border-left-color: var(--accent);
  background: var(--paper-hi); padding: 1.1rem 1.1rem .95rem; margin-bottom: 2rem;
}
.field--lead .notice { margin: .9rem 0 0; }
.field__step {
  float: right; color: var(--accent); letter-spacing: .16em;
}
.field__row { display: flex; gap: .6rem; align-items: stretch; }
.field__row input { flex: 1; min-width: 0; }
.field__row .btn { white-space: nowrap; flex: none; }
@media (max-width: 520px) { .field__row { flex-direction: column; } }
/* A row that sits under its control rather than beside it — the draft button
   belongs to the textarea above it, not to the hint below. */
.field__row--after { margin-top: .5rem; }

/* A box the page reader filled. Cleared the moment it is edited, so the mark
   only ever means "nobody has looked at this yet". */
.field .is-guess { border-style: dashed; border-color: var(--accent); }

.shot {
  margin: .6rem 0 0; border: 1.5px solid var(--rule-hard);
  width: 108px; height: 108px; background: var(--paper-hi);
}
.shot img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* Sections a proposed one would collide with. */
.overlap {
  border: 1.5px solid var(--accent); background: var(--accent-lo);
  padding: 1rem 1.1rem; margin-bottom: 1.35rem; font-size: .88rem;
}
.overlap--clear { border-color: var(--rule-hard); background: var(--paper-hi); }
.overlap p { margin: 0 0 .7rem; line-height: 1.5; }
.overlap strong { display: block; font: 600 .68rem/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; margin-bottom: .5rem; }
.overlap ul { list-style: none; margin: 0; padding: 0; }
.overlap li { padding: .55rem 0; border-top: 1px solid var(--rule); }
.overlap li a { color: var(--accent); font-weight: 600; text-decoration: none; }
.overlap li a:hover { text-decoration: underline; }
.overlap li span, .overlap li em {
  display: block; font: 400 .74rem/1.45 var(--mono); color: var(--ink-soft); font-style: normal;
}
.overlap li em { opacity: .8; }

.check {
  display: flex; gap: .7rem; align-items: flex-start;
  margin-bottom: 1.6rem; font-size: .88rem; line-height: 1.5; cursor: pointer;
}
.check input { width: 18px; height: 18px; margin-top: .12rem; accent-color: var(--accent); flex: none; }

.btn {
  appearance: none; cursor: pointer;
  font: 600 .74rem/1 var(--mono); letter-spacing: .16em; text-transform: uppercase;
  padding: .95rem 1.5rem;
  background: var(--ink); color: var(--paper);
  border: 1.5px solid var(--ink);
  transition: background .2s var(--ease), color .2s, transform .1s;
  text-decoration: none; display: inline-block;
}
.btn:hover { background: var(--accent); border-color: var(--accent); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn--ghost { background: none; color: var(--ink); }
.btn--ghost:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn--sm { padding: .6rem 1rem; font-size: .66rem; }

.notice {
  border: 1.5px solid var(--rule-hard); padding: 1rem 1.1rem;
  font-size: .88rem; line-height: 1.5; margin-bottom: 1.4rem;
  background: var(--paper-hi);
}
.notice--bad { border-color: var(--accent); background: var(--accent-lo); color: var(--ink); }
.notice--good { border-left-width: 5px; border-left-color: var(--accent); }
.notice strong { display: block; font: 600 .68rem/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; margin-bottom: .5rem; }

/* ============================================================
   MISC
   ============================================================ */

.crumb { padding-top: 1.4rem; font: 500 .66rem/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.crumb a { text-decoration: none; }
.crumb a:hover { color: var(--accent); }
.crumb i { font-style: normal; opacity: .4; padding: 0 .5rem; }

.empty { padding: 3.5rem 0; text-align: center; color: var(--ink-soft); border-bottom: 1px solid var(--rule); }
.empty p { max-width: 40ch; margin: 0 auto 1.2rem; }

.loading { padding: 5rem 0; text-align: center; }
.loading span {
  display: inline-block; width: 10px; height: 10px; background: var(--accent);
  animation: pulse 1s var(--ease) infinite;
}
.loading span:nth-child(2) { animation-delay: .15s; }
.loading span:nth-child(3) { animation-delay: .3s; }
@keyframes pulse { 0%, 100% { opacity: .2; transform: scale(.7); } 50% { opacity: 1; transform: scale(1); } }

.filters { display: flex; gap: .5rem; flex-wrap: wrap; padding: 1rem 0; }
.filters button {
  font: 500 .64rem/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  background: none; border: 1px solid var(--rule); padding: .5rem .8rem; cursor: pointer; color: var(--ink-soft);
}
.filters button:hover { border-color: var(--rule-hard); color: var(--ink); }
.filters button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.searchbar { position: relative; padding: 1rem 0 .4rem; }
.searchbar input {
  width: 100%; font-family: var(--mono); font-size: .9rem;
  background: transparent; border: 0; border-bottom: 1.5px solid var(--rule-hard);
  padding: .7rem 0 .7rem 1.7rem; color: var(--ink);
}
.searchbar input:focus { outline: 0; border-color: var(--accent); }
.searchbar input::placeholder { color: var(--ink-soft); opacity: .7; }
.searchbar::before {
  content: "⌕"; position: absolute; left: 0; top: 1.55rem; font-size: 1.25rem; color: var(--ink-soft);
}

/* front-page search sits under the hero CTAs and runs the full column. It was
   held to the lede's measure to match the text above it, but a search field is
   a target rather than something to read, and the short rule under it read as
   an unfinished line. */
.hero__search { margin-top: 1.6rem; padding-bottom: 0; }
.hero__search input { font-size: 1rem; }

.linkish {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--ink-soft);
}
.linkish:hover { color: var(--accent); }

/* staggered reveal on view mount */
.stagger > * { animation: rise .55s var(--ease) both; }
.stagger > *:nth-child(1) { animation-delay: .02s; }
.stagger > *:nth-child(2) { animation-delay: .05s; }
.stagger > *:nth-child(3) { animation-delay: .08s; }
.stagger > *:nth-child(4) { animation-delay: .11s; }
.stagger > *:nth-child(5) { animation-delay: .14s; }
.stagger > *:nth-child(6) { animation-delay: .17s; }
.stagger > *:nth-child(n+7) { animation-delay: .2s; }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ============================================================
   COLOPHON
   ============================================================ */

.colophon {
  position: relative; z-index: 2;
  border-top: 1.5px solid var(--rule-hard);
  margin-top: 4rem;
  background: var(--paper-lo);
}
.colophon__grid {
  max-width: var(--maxw); margin-inline: auto;
  padding: clamp(2rem, 5vw, 3.4rem) var(--gut);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 2rem;
}
.colophon h4 {
  text-transform: uppercase; font-size: .92rem; margin-bottom: .6rem;
}
.colophon p { margin: 0; font-size: .84rem; line-height: 1.55; color: var(--ink-soft); max-width: 40ch; }
.colophon em { font-style: normal; color: var(--ink); font-weight: 600; }
.colophon__rule {
  border-top: 1px solid var(--rule);
  max-width: var(--maxw); margin-inline: auto;
  padding: .9rem var(--gut);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  font: 500 .62rem/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft);
}
.colophon__ver { color: var(--accent); }

@media (max-width: 640px) {
  .entry { grid-template-columns: 2.2rem 62px minmax(0,1fr); gap: 0 .9rem; }
  .entry .vote-wrap { grid-column: 2 / -1; flex-direction: row; align-items: center; gap: .8rem; margin-top: .9rem; }
  .plate__mono { font-size: 46px; }
  .entry .vote { flex-direction: row; width: auto; }
  .entry .vote__score { border-block: 0; border-inline: 1.5px solid var(--rule-hard); min-width: 46px; display: grid; place-items: center; }
  .meter { width: 90px; }
  /* Must match the compounded selector above to win. */
  .stamp.hero__stamp { position: static; margin: 0 0 1.4rem auto; transform: rotate(-6deg); }
}

/* ============================================================
   IMAGE QUEUE (admin)
   The register's own type and rules, deliberately — this is an editorial
   screen, not a separate product, and an admin judging illustrations should
   see them in the surroundings a reader will.
   ============================================================ */

.admin { padding-bottom: 5rem; }

.admin-warn {
  border-left: 3px solid var(--accent);
  padding: .75rem .9rem; margin: 0 0 1.6rem;
  font-size: .84rem; line-height: 1.5; background: var(--accent-lo);
}
.admin-warn code { font: 500 .8rem var(--mono); }

.admin-tabs { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.8rem; }
.admin-tab {
  font: 500 .68rem/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  padding: .62rem .9rem; background: none; cursor: pointer;
  border: 1.5px solid var(--rule); color: var(--ink-soft);
}
.admin-tab[aria-selected="true"] { border-color: var(--rule-hard); color: var(--ink); background: var(--paper-hi); }
.admin-tab .num { margin-left: .5rem; color: var(--accent); }

/* The sweep sits above the cards it will fill, on the same two-column grid the
   cards use, so its button lands in the column their thumbnails do. */
.admin-sweep {
  display: grid; grid-template-columns: minmax(0, 1fr) 15rem; gap: 1.4rem;
  align-items: start; padding: 1.2rem 1.2rem 1.3rem;
  background: var(--paper-hi); border: 1.5px solid var(--rule-hard);
}
.admin-sweep__text p { margin: 0 0 .5rem; font-size: .86rem; line-height: 1.55; max-width: 62ch; }
.admin-sweep__text p:last-child { margin-bottom: 0; }
.admin-sweep__text .eyebrow { line-height: 1.7; }
.admin-sweep__act { display: grid; gap: .2rem; justify-items: start; }
.admin-sweep__act .admin-msg { margin: 0; }
@media (max-width: 640px) { .admin-sweep { grid-template-columns: minmax(0, 1fr); } }

.admin-card {
  display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 1.4rem;
  padding: 1.4rem 0; border-top: 1px solid var(--rule);
}
.admin-card--report { grid-template-columns: minmax(0, 1fr); }
.admin-card.is-target { box-shadow: -1.2rem 0 0 var(--accent-lo), 1.2rem 0 0 var(--accent-lo); background: var(--accent-lo); }

.admin-card__now { display: grid; gap: .5rem; justify-items: center; }
.admin-card__now .thumb { width: 120px; height: 120px; }
.admin-none {
  display: grid; place-items: center; width: 100%; height: 100%;
  font: 500 .6rem var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); border: 1px dashed var(--rule);
}

.admin-card__body h3 { font-size: 1.06rem; margin: 0 0 .45rem; line-height: 1.3; }
.admin-card__body h3 a { text-decoration: none; color: inherit; }
.admin-card__body h3 a:hover { color: var(--accent); }
.admin-card__meta { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin: 0 0 .8rem; }
.admin-card__meta .num { font-size: .62rem; color: var(--ink-soft); letter-spacing: .08em; }
.admin-card__acts { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .8rem; }

.admin-flagged {
  font-size: .82rem; margin: 0 0 .8rem; color: var(--accent);
  border-left: 2px solid var(--accent); padding-left: .6rem;
}

.admin-drop {
  border: 1.5px dashed var(--rule); padding: 1.15rem; text-align: center; cursor: pointer;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.admin-drop p { margin: 0; font-size: .8rem; color: var(--ink-soft); }
.admin-drop:hover, .admin-drop:focus-visible { border-color: var(--rule-hard); outline: 0; }
.admin-drop.is-over { border-color: var(--accent); background: var(--accent-lo); }
.admin-drop.is-over p { color: var(--accent); }

.admin-url { display: flex; gap: .5rem; margin-top: .6rem; flex-wrap: wrap; }
.admin-url input {
  flex: 1 1 16rem; min-width: 0;
  font: 400 .82rem var(--mono); padding: .5rem .65rem;
  border: 1.5px solid var(--rule); background: var(--paper);
}
.admin-url input:focus { outline: 0; box-shadow: 3px 3px 0 var(--accent); }

.admin-msg { font-size: .8rem; color: var(--ink-soft); margin: .7rem 0 0; min-height: 1.1em; }

/* The render bar. Square, ruled and flat like everything else here — the
   width is set from script, so nothing but the easing lives in the CSS. The
   transition is what keeps a once-a-second update from stepping. */
.rbar { height: 6px; margin: .8rem 0 0; border: 1.5px solid var(--rule-hard); background: var(--paper); }
.rbar i { display: block; height: 100%; width: 0; background: var(--accent); transition: width 1s linear; }
@media (prefers-reduced-motion: reduce) { .rbar i { transition: none; } }

/* The correction form, on an entry page and inside a queue card alike. */
.editor {
  border: 1.5px solid var(--rule-hard); border-left-width: 5px; border-left-color: var(--accent);
  background: var(--paper-hi); padding: 1.1rem 1.1rem .6rem; margin-top: 1.2rem;
}
.editor .eyebrow { margin-bottom: .9rem; color: var(--accent); }
.editor .field { margin-bottom: 1rem; }
.editor textarea { min-height: 110px; }
.editor .notice { margin: .4rem 0 .9rem; }
.editor .btn { margin: 0 .4rem .6rem 0; }

.detail__edit { margin-top: 1.6rem; }
.detail__edit .hint { font: 400 .74rem/1.45 var(--mono); color: var(--ink-soft); margin-top: .5rem; }

.admin-supplied {
  font: 400 .78rem/1.45 var(--mono); color: var(--ink-soft);
  border-left: 3px solid var(--accent); padding: .1rem 0 .1rem .7rem; margin: .7rem 0 0;
}
.admin-supplied a { color: var(--accent); }

.admin-result {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 1rem;
  margin-top: 1.1rem; padding: 1rem; border: 1.5px solid var(--rule-hard);
}
.admin-result figure { margin: 0; display: grid; gap: .35rem; justify-items: center; }
.admin-result img { width: 150px; height: 150px; object-fit: contain; background: #fff; }
.admin-result figcaption {
  font: 500 .6rem var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft);
}
.admin-arrow { align-self: center; color: var(--ink-soft); }
.admin-result__acts { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; flex: 1 1 12rem; }
.admin-result__acts .admin-warn { flex-basis: 100%; margin: 0 0 .4rem; }
.admin-result__acts .eyebrow { flex-basis: 100%; }

.admin-report__reason { font-size: .9rem; line-height: 1.5; margin: 0 0 .6rem; max-width: 68ch; }

/* The picker: what the image search found, as a grid you click. Above the
   sticky header at z-index 40, and a child of the body so no scrolling or
   transformed ancestor can clip a fixed overlay. */
.picker {
  position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, .55);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 3vh 1rem; overflow: auto;
}
.picker__panel {
  width: min(64rem, 100%); background: var(--paper);
  border: 1.5px solid var(--rule-hard); padding: 1.2rem;
}
.picker__head {
  display: flex; flex-wrap: wrap; gap: .8rem; align-items: flex-start;
  justify-content: space-between; margin-bottom: 1rem;
}
.picker__head h3 { font-size: 1.06rem; margin: .25rem 0 0; line-height: 1.3; }
.picker__acts { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }

.picker__grid {
  display: grid; gap: .8rem;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
}
.picker__tile {
  display: grid; gap: .35rem; padding: .4rem; text-align: left; font: inherit;
  background: var(--paper-hi); border: 1.5px solid var(--rule); cursor: pointer;
}
.picker__tile:hover, .picker__tile:focus-visible {
  border-color: var(--accent); outline: 0; box-shadow: 3px 3px 0 var(--accent);
}
.picker__shot { display: block; aspect-ratio: 1; background: #fff; }
.picker__shot img { width: 100%; height: 100%; object-fit: contain; }
.picker__cap {
  font: 500 .58rem var(--mono); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-soft); overflow-wrap: anywhere;
}
/* Hotlink-blocked here, but the service fetches server-side and may still get
   it — so the tile says so and stays clickable. */
.picker__tile.is-blank .picker__shot { display: grid; place-items: center; background: var(--paper); }
.picker__tile.is-blank img { display: none; }
.picker__tile.is-blank .picker__shot::after {
  content: 'no preview'; font: 500 .58rem var(--mono);
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft);
}

/* The section a proposal would become, editable before it is created. */
.admin-trade {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0 .8rem; border-top: 1px solid var(--rule); padding-top: .9rem; margin-top: .4rem;
}
.admin-trade .field { margin-bottom: .8rem; }
.admin-trade .field input { padding: .55rem .65rem; font-size: .9rem; }

.admin-box .tag { margin-left: .4rem; vertical-align: middle; }

@media (max-width: 640px) {
  .admin-card { grid-template-columns: minmax(0, 1fr); }
  .admin-card__now { justify-items: start; }
}
