/* ─────────────────────────────────────────────────────────────
   Indifferent Ketchup -- flair layer

   Opt-in identity layer, scoped to a data-flair attribute. Sites
   that do not set the attribute render byte-identically to today.
   Two intensity tiers:

     data-flair="trace"   identity signals without layout disruption
                          (cream, hard-offset shadow, aside)
     data-flair="loud"    trace plus display scale, red band, rotation,
                          dither, and asymmetric gutters

   Load order: tokens.css, fonts.css, components.css, then this file.
   Loading flair.css before components.css mostly works on specificity
   alone, which is what makes getting it wrong confusing to debug.
   No !important needed anywhere: data-flair attribute selectors
   already outrank components.css's bare class selectors.

   Full rationale: ../DESIGN.md
   ───────────────────────────────────────────────────────────── */

/* ══════════════════════ shared base (trace tier) ══════════════════════
   The selector is enumerated -- [data-flair="trace"], [data-flair="loud"] --
   never the bare data-flair attribute. A bare attribute selector matches any value,
   so a typo like data-flair="loud " would silently ship the trace tier
   instead of nothing, violating the unrecognized-value behavior the spec
   requires. Adding a third tier later extends the selector list. */

/* ── aside: mono, small, muted -- an interruption in a margin position ──
   Distinct from .mono-label (12px, 500 weight, --text-muted) in that
   .aside is one step smaller (11px) and receded to --text-faint rather
   than --text-muted. The label names a thing; the aside comments on it
   from the margin. A third mono text class earns its place because it
   fills the register-shifting role described in voice/VOICE-SPEC.md §5,
   which neither .mono-label (data labelling) nor body prose (readable
   flow) covers. */
[data-flair="trace"] .aside,
[data-flair="loud"] .aside {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-faint);
  letter-spacing: 0.02em;
  line-height: 1.5;
}

/* ── cream surface token ── */
[data-flair="trace"],
[data-flair="loud"] {
  --flair-surface: var(--flair-cream);
  --flair-on-surface: var(--brand-ink);
}

/* ── .slab-cream: one cream block per page, loud tier only ──
   The original constraint was cream on small elements only, on the
   grounds that a large warm surface fights the Surface Rule's cold
   luminance ladder. That was over-weighted: restricting cream to chips
   removed the one move that makes the warm/cold contrast actually
   register at page scale.

   The constraint that replaces it: ONE per page, bounded height, and
   never the page or a panel background. It is a block that interrupts
   the cold canvas, the same way .band-red-once interrupts it, and it
   follows the same once-per-page discipline for the same reason.

   --brand-ink on cream measures 14.99:1. */
[data-flair="loud"] .slab-cream {
  background: var(--flair-cream);
  color: var(--brand-ink);
  padding: var(--sp-8) var(--sp-6);
  box-shadow: var(--flair-shadow);
  max-height: 40vh;
  overflow: hidden;

  /* Square to the page grid, full width of its container, no tilt and no
     torn silhouette. The warm/cold contrast is doing the work here; it does
     not need the block to also sit crooked. A clean rectangle at this scale
     reads as deliberate placement. A tilted one reads as an accident that
     nobody fixed. */
}
[data-flair="loud"] .slab-cream .display-loud,
[data-flair="loud"] .slab-cream .aside {
  color: var(--brand-ink);
}

/* ── emphasis inside a display line ──
   One word in a heading picked out in --brand, on its own baseline and in
   its own box. Earlier revisions knocked the word off the baseline and
   rotated it; that read as damage rather than as emphasis. Color carries
   the same "this word is different" signal without breaking the line, and
   it survives at every viewport width instead of only wide ones.
   --brand on --bg measures 5.19:1. */
[data-flair="loud"] .display-loud .accent {
  color: var(--brand);
}

/* ── .sticker-row: badges in an even, aligned row ──
   Earlier revisions overlapped these with alternating rotations. It read
   as clutter, and at 0.14 alpha the badge fills let one label show through
   the next. An even row on a single baseline, sharing the --sp-3 rhythm
   the rest of the system uses, reads as composed instead. */
[data-flair="loud"] .sticker-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}

/* ── .stack-tight: gapless stacking ──
   Removes the vertical rhythm between full-bleed blocks so the red band,
   the dither, and the cream slab slam into each other with no rest between
   them. The absence of breathing room is the point: an even 24px rhythm
   reads calm, and calm is the one thing this tier is not for.

   No !important here, per design D4. Consumers must not set an inline
   margin on the children of .stack-tight, since an inline style outranks
   every selector and would silently reopen the gap. Spacing between these
   blocks belongs to the class, not to the markup. */
[data-flair="loud"] .stack-tight > * { margin-top: 0; }
[data-flair="loud"] .stack-tight > * + * { margin-top: 0; }

/* ══════════════════════ loud tier ══════════════════════ */

/* ── oversized display ── */
[data-flair="loud"] .display-loud {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(48px, 12vw, 120px);
  line-height: 0.95;
  letter-spacing: -0.03em;
  color: var(--text);
}

/* ── full-bleed red band, once per page, loud only ──
   Uses --brand fill with --brand-ink text (5.19:1, passes AA).
   White text on --brand fails AA at 3.57:1, do not use it. */
[data-flair="loud"] .band-red-once {
  background: var(--brand);
  color: var(--brand-ink);
  /* Full-bleed background, but the content inside keeps the page's own
     gutter on both sides so the band's text stays on the same left edge as
     every other block on the page. A full-bleed band whose text starts at
     the viewport edge is the tell that the bleed was an accident. */
  padding: var(--sp-6) var(--page-padding);
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}
[data-flair="loud"] .band-red-once .display-loud {
  color: var(--brand-ink);
}

/* ── dither band: repeating-conic-gradient checkerboard, hard stops ──
   4px cells, cream at --flair-dither-alpha. 0% 25% and 0% 50% stop pairs
   share start and end positions, so no two adjacent stops differ -- this
   is a quantized pixel texture, not a continuous gradient. Band height is
   32px, within the 24-48px range. Never a large-area fill. */
[data-flair="loud"] .band-dither {
  height: 32px;
  background: repeating-conic-gradient(
    var(--flair-cream) 0% 25%, transparent 0% 50%
  ) 0 0 / 4px 4px;
  opacity: var(--flair-dither-alpha);
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

/* ── no rotation, no overlap, no gutter asymmetry ──
   Earlier revisions carried .sticker-ccw / .sticker-cw rotation classes,
   negative-margin overlap helpers, and a .container-asym with a right
   gutter 2.5x the left. All three are gone.

   The loud tier gets its force from scale, from full-bleed color blocks,
   and from the warm/cold contrast of cream against the canvas. Those are
   loud and they are square. Tilting, colliding, and unbalancing on top of
   them stopped adding energy and started adding noise: the page read
   unfinished rather than emphatic.

   Everything in this tier now sits on the same grid, on the same baseline,
   in the same rhythm as the base system. Same volume, straight lines. */

