/* ═══════════════════════════════════════════════════════════════════════════
   RAPCANON — THE DEPTH + OPULENCE LAYER (v3)
   Translated 2026-08-11 from an eyes-on pass over launchkits.dev.

   That site is LIGHT (warm cream paper) and this one is dark, so nothing was
   copied literally. What transfers is the LOGIC, and it is four ideas:

     1. Every section is announced by a small-caps rule-flanked eyebrow, so the
        page reads as a set of deliberate chapters rather than one long scroll.
     2. Feature panels carry real TEXTURE plus a faint engineered line-art plate
        behind the content, with print-style corner ticks. Texture is what stops
        a large surface from reading as an empty div.
     3. Taxonomy is COLOUR-CODED per item. Variety inside a uniform system is
        what makes a dense grid scannable instead of exhausting.
     4. Hover is a REWARD, not a state change. A lift, a warming border, and a
        slow sheen that crosses the card once. Subtle enough to bear repetition,
        felt enough to pull the next click.

   Every plate here is inline SVG: zero licensing exposure, zero external
   requests, and nothing that can 404 in a year. Loaded after theme.css.
   ═══════════════════════════════════════════════════════════════════════════ */

/* soft vignette: pulls the eye toward the centre column with no visible edge */
body { box-shadow: inset 0 0 240px 60px rgba(0,0,0,.34); }

/* ── 1. RULE-FLANKED EYEBROW ─────────────────────────────────────────── */
.rule-eyebrow {
  display: flex; align-items: center; gap: 16px; justify-content: center;
  font-family: var(--mono); font-size: .7rem; font-weight: 500;
  letter-spacing: .28em; text-transform: uppercase; color: var(--text-dim);
  margin: 0 0 18px;
}
.rule-eyebrow::before, .rule-eyebrow::after {
  content: ""; height: 1px; width: min(80px, 12vw);
  background: linear-gradient(90deg, transparent, var(--line));
}
.rule-eyebrow::after { background: linear-gradient(90deg, var(--line), transparent); }
.rule-eyebrow.left { justify-content: flex-start; }
.rule-eyebrow.left::before { display: none; }

/* ── 2. FEATURE PANEL: texture + engineered plate + corner ticks ─────── */
.panel {
  position: relative; border-radius: 20px; overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--shadow-2);
  background:
    radial-gradient(120% 130% at 88% 8%, rgba(255,90,60,.16), transparent 58%),
    radial-gradient(90% 110% at 4% 96%, rgba(63,199,187,.10), transparent 60%),
    linear-gradient(160deg, var(--paper-3), var(--paper));
}
/* the engineered plate: a technical grid and an orbit, DRAWN not photographed */
.panel::before {
  content: ""; position: absolute; inset: 0; opacity: .55; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='560' height='400' viewBox='0 0 560 400'%3E%3Cg fill='none' stroke='%23ffffff' stroke-opacity='0.07' stroke-width='1'%3E%3Cpath d='M0 340h560M0 300h560M0 260h560M0 220h560'/%3E%3Cpath d='M60 400V0M140 400V0M220 400V0M300 400V0M380 400V0M460 400V0'/%3E%3C/g%3E%3Cg fill='none' stroke='%23ff5a3c' stroke-opacity='0.18'%3E%3Ccircle cx='430' cy='140' r='96'/%3E%3Ccircle cx='430' cy='140' r='58'/%3E%3Cpath d='M120 330 L230 250 L310 286 L430 140'/%3E%3C/g%3E%3Cg fill='%23ff5a3c' fill-opacity='0.36'%3E%3Ccircle cx='230' cy='250' r='3.5'/%3E%3Ccircle cx='310' cy='286' r='3.5'/%3E%3Ccircle cx='430' cy='140' r='4.5'/%3E%3C/g%3E%3C/svg%3E");
  background-size: cover; background-position: right center; background-repeat: no-repeat;
}
/* print crop marks: the cheapest possible signal that a surface was composed */
.panel::after {
  content: ""; position: absolute; inset: 14px; pointer-events: none;
  background:
    linear-gradient(var(--line-soft),var(--line-soft)) left top/14px 1px no-repeat,
    linear-gradient(var(--line-soft),var(--line-soft)) left top/1px 14px no-repeat,
    linear-gradient(var(--line-soft),var(--line-soft)) right top/14px 1px no-repeat,
    linear-gradient(var(--line-soft),var(--line-soft)) right top/1px 14px no-repeat,
    linear-gradient(var(--line-soft),var(--line-soft)) left bottom/14px 1px no-repeat,
    linear-gradient(var(--line-soft),var(--line-soft)) left bottom/1px 14px no-repeat,
    linear-gradient(var(--line-soft),var(--line-soft)) right bottom/14px 1px no-repeat,
    linear-gradient(var(--line-soft),var(--line-soft)) right bottom/1px 14px no-repeat;
}
.panel-body { position: relative; z-index: 2; padding: clamp(26px, 3.5vw, 46px); }
/* frosted card holding the copy, so type never fights the plate behind it */
.panel-glass {
  max-width: 60ch;
  background: linear-gradient(180deg, rgba(21,22,27,.66), rgba(21,22,27,.40));
  backdrop-filter: blur(7px); border: 1px solid var(--line-soft);
  border-radius: 16px; padding: clamp(22px, 2.6vw, 34px);
}

/* ── 3. TAXONOMY PILLS (per-item hue) + LIVE STATUS PILL ─────────────── */
.pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 0; }
.pill {
  --h: var(--accent);
  display: inline-block;
  font-family: var(--mono); font-size: .67rem; letter-spacing: .12em; text-transform: uppercase;
  padding: 5px 11px; border-radius: 999px; color: var(--h);
  border: 1px solid color-mix(in srgb, var(--h) 42%, transparent);
  background: color-mix(in srgb, var(--h) 11%, transparent);
  transition: background .18s ease, transform .18s ease;
}
a.pill:hover { background: color-mix(in srgb, var(--h) 20%, transparent); transform: translateY(-1px); color: var(--h); }
.pill.h-data   { --h: var(--secondary); }
.pill.h-econ   { --h: #f2b544; }
.pill.h-tour   { --h: #8f8cf5; }
.pill.h-rights { --h: #f06ba8; }
.pill.h-chart  { --h: #5bc47a; }

.status {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: .67rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--secondary-light); padding: 5px 12px 5px 10px; border-radius: 999px;
  border: 1px solid rgba(63,199,187,.34); background: rgba(63,199,187,.08);
}
.status .dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--secondary);
  box-shadow: 0 0 0 0 rgba(63,199,187,.6); animation: ot-pulse 2.6s infinite;
}
@keyframes ot-pulse { 70% { box-shadow: 0 0 0 7px rgba(63,199,187,0); } 100% { box-shadow: 0 0 0 0 rgba(63,199,187,0); } }

/* ── 4. FILTER CHIP ROW (with counts) ────────────────────────────────── */
.chiprow { display: flex; flex-wrap: wrap; gap: 8px; margin: 22px 0 30px; }
.chip {
  display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--paper-2); color: var(--text-dim);
  font-size: .85rem; transition: border-color .18s ease, color .18s ease, background .18s ease;
}
.chip .cdot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .85; }
.chip .count { font-family: var(--mono); font-size: .73rem; color: var(--text-faint); }
.chip:hover { border-color: rgba(255,90,60,.4); color: var(--text); }
.chip.on { background: var(--accent); border-color: transparent; color: #14151a; font-weight: 600; }
.chip.on .count { color: rgba(20,21,26,.72); }

/* ── 5. CIRCULAR THUMBNAILS (the artist row) ─────────────────────────── */
.facerow { display: flex; flex-wrap: wrap; gap: 24px; margin: 26px 0 0; }
/* display:block is LOAD-BEARING on both. .face is an <a> and .ring is a <span>, both inline by
   default, and width/height are silently IGNORED on inline elements. Without these the plates
   render as tall rectangles and the border-radius never makes a circle. Caught by eyes-on
   2026-08-11; every programmatic check passed because the images were loading correctly. */
.face { display: block; width: 96px; text-align: center; }
.face .ring {
  display: block;
  width: 96px; height: 96px; border-radius: 50%; position: relative; overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--shadow-1), inset 0 1px 0 var(--lit);
  background: linear-gradient(160deg, var(--paper-3), var(--paper));
  transition: transform .24s cubic-bezier(.2,.7,.3,1), border-color .24s ease;
}
.face .ring img, .face .ring svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.face:hover .ring { transform: translateY(-3px) scale(1.03); border-color: rgba(255,90,60,.45); }
.face .nm { display: block; margin-top: 10px; font-size: .81rem; color: var(--text); line-height: 1.3; }
.face .mt { display: block; font-family: var(--mono); font-size: .71rem; color: var(--secondary-light); }

/* ── 6. HOVER AS REWARD: one slow sheen across the card ──────────────── */
.card::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.06) 50%, transparent 62%);
  transform: translateX(-120%);
  transition: opacity .2s ease, transform .8s cubic-bezier(.25,.6,.3,1);
}
.card:hover::after { opacity: 1; transform: translateX(120%); }

/* a number used as a graphic element, for infographic rows */
.bigfig {
  font-family: var(--serif); font-weight: 900; font-size: clamp(2.4rem, 5.4vw, 4rem);
  line-height: .9; letter-spacing: -.04em; color: var(--secondary-light);
}
.bigfig small {
  display: block; font-family: var(--sans); font-weight: 400; font-size: .88rem;
  letter-spacing: 0; color: var(--text-dim); margin-top: 10px; line-height: 1.5;
}
.figrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 32px; }

@media (prefers-reduced-motion: reduce) {
  .status .dot { animation: none; }
  .card::after { display: none; }
  .face:hover .ring, a.pill:hover { transform: none; }
}

/* ── 7. FIGURES (the house figure system) ────────────────────────────────
   A figure must carry information the prose cannot. A picture that restates
   the sentence above it is decoration, and decoration on a data publication
   actively costs credibility. Two classes only, and they are never mixed:
   MECHANISM figures (labelled illustrative) and DATA figures (labelled with
   their n and their source). The caption states which. */
figure { margin: 34px 0; }
figure img, figure svg {
  width: 100%; height: auto; display: block;
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: 14px; box-shadow: var(--shadow-1);
}
figcaption {
  color: var(--text-dim); font-size: .84rem; margin-top: 12px; line-height: 1.55;
  padding-left: 14px; border-left: 2px solid var(--line);
}
figcaption .src { color: var(--text-faint); font-family: var(--mono); font-size: .78rem; display: block; margin-top: 4px; }
/* a non-link face (example plates carry no destination) must not look clickable */
span.face { cursor: default; }
span.face:hover .ring { transform: none; border-color: var(--line); }

/* ── 8. EMAIL CAPTURE (magnet doctrine: a specific deliverable, never "updates") ──── */
.capture { display:flex; gap:10px; justify-content:center; flex-wrap:wrap; max-width:520px; margin:0 auto; }
.capture input {
  flex:1 1 260px; background:var(--paper-2); color:var(--text); border:1px solid var(--line);
  border-radius:10px; padding:13px 16px; font-size:1rem; font-family:var(--sans);
}
.capture input:focus { outline:none; border-color:var(--accent); }
.capture input::placeholder { color:var(--text-faint); }
.cap-note { font-family:var(--mono); font-size:.78rem; color:var(--text-faint); margin-top:14px; line-height:1.5; }
.cap-note.ok { color:var(--secondary-light); }
.cap-note.err { color:var(--accent-light); }

/* ── 9. THE ATMOSPHERE LAYER (added 2026-08-12) ──────────────────────────
   A deep, textured, slowly-moving field of rising embers behind everything.

   WHY IT EXISTS. The dark base was flat, and a flat black on a publication
   reads as unfinished rather than as restraint. This gives the page air and
   depth, and it carries a symbolic register the operator wanted: cinders
   rising off something that is already burning. It is never stated and never
   literal. If a reader only ever registers "this feels alive", it worked.

   ★ COLOUR RULE, LOAD-BEARING. theme.css reserves vermillion for VOICE and
   cyan for MEASUREMENT and forbids decorating with either. Embers therefore
   get their OWN token, --ember, a desaturated amber/ash that is deliberately
   NOT --accent. Decorating with the accent would spend the signal, and the
   next real accent on the page would cost more. Do not "simplify" this by
   pointing --ember at --accent.

   BUILT FOR CHEAPNESS. Transform + opacity only, so it stays on the
   compositor and never triggers layout. No external requests, no images, no
   canvas, no libraries. Fully disabled under prefers-reduced-motion, where it
   degrades to a still gradient rather than to nothing.
   ─────────────────────────────────────────────────────────────────────── */
:root {
  --ember:      #ffa86a;   /* atmosphere ONLY. never a signal, never a UI accent */
  --ember-deep: #c2542a;
}

.atmos {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden;
  contain: strict;                       /* isolate: this layer can never affect content layout */
}
/* content rides above the atmosphere */
body > header, body > main, body > footer, body > .wrap { position: relative; z-index: 1; }

/* 9a. the deep field: a low warm bloom from below, a cool high light, and a
       wide vignette. Three stops, all very low alpha, so it reads as air. */
.atmos::before {
  content: ""; position: absolute; inset: -10%;
  background:
    radial-gradient(78% 54% at 50% 110%, rgba(194,84,42,.34), transparent 70%),
    radial-gradient(46% 34% at 82% 98%,  rgba(255,168,106,.17), transparent 72%),
    radial-gradient(52% 40% at 14% -8%,  rgba(150,190,215,.045), transparent 72%);
  animation: atmos-breathe 26s ease-in-out infinite alternate;
}
@keyframes atmos-breathe {
  from { transform: translate3d(0,0,0) scale(1); opacity: .85; }
  to   { transform: translate3d(0,-1.6%,0) scale(1.05); opacity: 1; }
}

/* 9b. grain. A dark surface with no texture looks like a switched-off screen.
       feTurbulence at very low alpha gives it a tactile, printed quality. */
.atmos::after {
  content: ""; position: absolute; inset: 0; opacity: .30; mix-blend-mode: overlay;
  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='.86' 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");
}

/* 9c. the embers. Three depth tiers: far ones are small, dim and slow; near
       ones are larger, brighter and slightly out of focus. That focus split is
       what produces depth rather than a flat sprinkle of dots. */
.ember {
  position: absolute; bottom: -6vh; border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, var(--ember), var(--ember-deep) 55%, transparent 72%);
  opacity: 0; will-change: transform, opacity;
  animation-name: ember-rise; animation-timing-function: linear; animation-iteration-count: infinite;
}
.ember.t0 { width: 1.5px; height: 1.5px; filter: blur(.3px); --drift:   9px; }
.ember.t1 { width: 2.5px; height: 2.5px; filter: blur(.5px); --drift:  16px; }
.ember.t2 { width: 5px;   height: 5px;   filter: blur(1px);  --drift: -30px; }
.ember.t3 { width: 9px;   height: 9px;   filter: blur(3px);  --drift:  44px; }

@keyframes ember-rise {
  0%   { transform: translate3d(0, 0, 0) scale(.7); opacity: 0; }
  12%  { opacity: var(--peak, .5); }
  70%  { opacity: var(--peak, .5); }
  100% { transform: translate3d(var(--drift), -112vh, 0) scale(1.05); opacity: 0; }
}
.ember.t0 { --peak: .22; }
.ember.t1 { --peak: .46; }
.ember.t2 { --peak: .68; }
.ember.t3 { --peak: .40; }

/* a rare, brighter cinder. Scarcity is what keeps the effect from reading as
   a screensaver: the eye catches one occasionally rather than watching a field. */
.ember.hot { --peak: .92; box-shadow: 0 0 14px 3px rgba(255,168,106,.30); }

@media (prefers-reduced-motion: reduce) {
  .atmos::before { animation: none; }
  .ember { display: none; }
}
/* small screens: fewer, cheaper. The effect is atmosphere, not content. */
@media (max-width: 640px) {
  .ember.t3 { display: none; }
  .atmos::after { opacity: .22; }
}

/* 9d. THE HAZE PLANE (added 2026-08-12, second pass).
   The first pass had one field plus embers, which read as a sprinkle rather
   than as distance. Depth is not more particles, it is more PLANES that move
   at different rates. This adds the far/mid strata: large, heavily blurred
   volumes of warm light that drift very slowly, so the embers cross IN FRONT
   of something rather than in front of nothing.

   Deliberately enormous and deliberately near-invisible per element. If you can
   point at a blob, it is too strong. Blur is doing the work, not opacity. */
.haze { position: absolute; inset: -20%; pointer-events: none; }
.blob {
  position: absolute; border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, var(--ember), transparent 66%);
  will-change: transform, opacity;
  animation-name: haze-drift; animation-timing-function: ease-in-out;
  animation-iteration-count: infinite; animation-direction: alternate;
}
.blob.b1 { width: 46vw; height: 46vw; left: -8%;  bottom: -14%; opacity: .050; filter: blur(90px);  animation-duration: 48s; }
.blob.b2 { width: 34vw; height: 34vw; right: -6%; bottom:  -8%; opacity: .042; filter: blur(76px);  animation-duration: 61s; }
.blob.b3 { width: 26vw; height: 26vw; left:  38%; bottom:  16%; opacity: .030; filter: blur(64px);  animation-duration: 74s; }
.blob.b4 { width: 58vw; height: 58vw; left:  16%; top:    -26%; opacity: .022; filter: blur(120px); animation-duration: 88s;
           background: radial-gradient(circle at 50% 50%, #8fb6d6, transparent 68%); }  /* the cool high plane, for separation */

@keyframes haze-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(4vw, -3vh, 0) scale(1.14); }
}

@media (prefers-reduced-motion: reduce) { .blob { animation: none; } }
@media (max-width: 640px) { .blob.b3, .blob.b4 { display: none; } .blob { filter: blur(60px); } }

/* ── 10. TOOL SURFACES (Beat Licence Matrix, 2026-08-12) ─────────────────
   A verdict is the whole product of a lookup tool, so it gets the strongest
   type on the page and a colour that carries meaning rather than decoration.

   COLOUR NOTE: these are SEMANTIC states, which is exactly the case the theme
   reserves accent/secondary for. Permitted borrows measurement-cyan because a
   verdict is a resolved fact; Not-permitted borrows voice-vermillion because it
   is the publication saying no. Capped and Depends get neutral amber/slate so
   the palette never implies more certainty than the data has. */
.verdict {
  display: flex; align-items: center; gap: 12px;
  border-radius: 14px; padding: 18px 22px; margin: 26px 0;
  border: 1px solid var(--line); background: var(--paper-2);
}
.verdict .vlabel {
  font-family: var(--serif); font-weight: 900; letter-spacing: -.02em;
  font-size: clamp(1.5rem, 3.4vw, 2.1rem); line-height: 1;
}
.verdict::before { content: ""; width: 6px; align-self: stretch; border-radius: 3px; background: currentColor; }
.verdict.v-yes { color: var(--secondary-light); border-color: rgba(63,199,187,.34); background: rgba(63,199,187,.07); }
.verdict.v-no  { color: var(--accent-light);    border-color: rgba(255,90,60,.34);  background: rgba(255,90,60,.07); }
.verdict.v-cap { color: #f2b544;                border-color: rgba(242,181,68,.34); background: rgba(242,181,68,.07); }
.verdict.v-dep { color: var(--text-dim);        border-color: var(--line); }

/* the trap block: the single most useful thing on the page, so it is framed
   as an aside rather than buried in prose */
.trap {
  border-left: 3px solid var(--accent); background: rgba(255,90,60,.05);
  border-radius: 0 12px 12px 0; padding: 18px 22px; margin: 26px 0;
}
.trap strong { color: var(--accent-light); }
.chk { color: var(--text-dim); }
.limit {
  font-size: .9rem; color: var(--text-dim); border: 1px dashed var(--line);
  border-radius: 12px; padding: 16px 18px; background: var(--paper);
}

/* the full matrix. Scrolls inside its own container so the page body never
   scrolls horizontally on a phone. */
.matrix, .matrix-mini { width: 100%; border-collapse: collapse; font-size: .92rem; margin: 18px 0; }
.matrix th, .matrix td, .matrix-mini th, .matrix-mini td {
  border: 1px solid var(--line); padding: 10px 12px; text-align: left;
}
.matrix thead th, .matrix-mini thead th {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-dim); background: var(--paper); position: sticky; top: 0;
}
.matrix tbody th { font-weight: 500; color: var(--text); min-width: 15rem; }
.matrix td { text-align: center; font-family: var(--mono); font-size: .78rem; letter-spacing: .06em; }
.matrix td a { border-bottom: 1px dotted currentColor; }
.matrix td.v-yes, .matrix-mini td.v-yes { color: var(--secondary-light); }
.matrix td.v-no,  .matrix-mini td.v-no  { color: var(--accent-light); }
.matrix td.v-cap, .matrix-mini td.v-cap { color: #f2b544; }
.matrix td.v-dep, .matrix-mini td.v-dep { color: var(--text-dim); }
.matrix tbody tr:hover td, .matrix tbody tr:hover th { background: rgba(255,255,255,.022); }

/* the picker */
.picker { border: 1px solid var(--line); border-radius: 18px; background: var(--paper-2); padding: clamp(20px,2.6vw,30px); margin: 30px 0; box-shadow: var(--shadow-1); }
.pick-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; }
.pick-row label { display: block; font-family: var(--mono); font-size: .7rem; letter-spacing: .14em; text-transform: uppercase; color: var(--secondary-light); }
.pick-row select {
  display: block; width: 100%; margin-top: 8px; padding: 12px 14px; font-size: 1rem;
  font-family: var(--sans); color: var(--text); background: var(--paper); border: 1px solid var(--line); border-radius: 10px;
}
.pick-row select:focus { outline: none; border-color: var(--accent); }
.pk-out { margin-top: 6px; }
.pk-out p { margin: 14px 0 0; }

.tierdefs { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; }
.tierdef { border: 1px solid var(--line); border-radius: 14px; padding: 18px 20px; background: var(--paper-2); }
.tierdef h3 { margin: 0 0 8px; font-size: 1.02rem; display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.tierdef h3 span { font-family: var(--mono); font-size: .74rem; color: var(--secondary-light); font-weight: 400; }
.tierdef p { margin: 0; color: var(--text-dim); font-size: .92rem; }

@media (max-width: 640px) { .matrix tbody th { min-width: 11rem; } }
