/**
 * KOL components — organism tier
 *
 * Component CSS that belongs to the organism layer (composite, multi-part
 * components). Atoms + molecules live elsewhere (see kol-components.css for
 * now; will split into kol-components-atoms.css / -molecules.css when the
 * volume justifies it).
 *
 * ─────────────────────────────────────────────────────────────────────
 * Table — src/components/organisms/Table.jsx
 * ─────────────────────────────────────────────────────────────────────
 *
 * Structural (applied by Table.jsx; do not use directly):
 *   .kol-table-wrapper            outer container — scroll, border, radius
 *   .kol-table                    the <table>
 *   .kol-table-thead              header bg + bottom border
 *   .kol-table-row                body row separator
 *
 * Cell classes (pass via column.className / column.headerClassName):
 *   .kol-table-cell-title         header cells — 12px mono, uppercase, nowrap
 *   .kol-table-cell-text          default body cell — 12px mono, nowrap
 *   .kol-table-cell-meta          wrapping description — 10px, max 24rem
 *   .kol-table-cell-meta-strong   same as -meta, full ink opacity
 *
 * Inline content (use inside cell render() funcs; no padding):
 *   .kol-table-meta               meta text, no cell padding
 *   .kol-table-meta-strong        same, full opacity
 *   .kol-table-pair               min-width 18rem container for key-value
 *   .kol-table-pill               base pill (combine with variant below)
 *   .kol-table-pill-light         pill — secondary surface bg
 *   .kol-table-pill-muted         pill — fg-16 bg
 *   .kol-table-pill-dark          pill — inverted ink
 *   .kol-table-token              inline code-token badge
 *
 * Variant (set via Table component's `variant` prop, not directly):
 *   .kol-table--simple            borderless, flush, no column dividers
 */

/* =============================================================================
 * Table
 * ============================================================================= */

.kol-table-wrapper {
  overflow-x: auto;
  scrollbar-width: none;
  /* opaque border stop — translucent fg-08 stacked with the collapsed table's
   * own borders composited into darker seams over gradients (2026-07-15 chess
   * audit finding 4); oq-* mirrors the same visual weight without alpha */
  border: 1px solid var(--kol-oq-08);
  border-radius: 4px;
  /* no scroll-edge paint — the 2026-07-28 ruling bans shadow bands, and the
   * surface-primary "cover" gradients that outlived it rendered as exactly
   * that band on any non-primary surface (brand app dark, 2026-08-09) */
}

.kol-table-wrapper::-webkit-scrollbar { display: none; }

.kol-table {
  width: 100%;
  min-width: 100%;
  border-collapse: collapse;
  text-align: left;
  font-family: var(--kol-font-family-mono);
  font-size: 0.8125rem;
  line-height: 1.5;
}

.kol-table-thead {
  background: var(--kol-fg-04);
  border-bottom: 1px solid var(--kol-oq-08);
}

.kol-table-row {
  border-bottom: 1px solid var(--kol-oq-08);
  vertical-align: top;
}

.kol-table-row:last-child { border-bottom: none; }

/* no text-transform (casing law 2026-07-15): headers render as authored —
 * consumers wanting caps author "DATE", not lowercase + CSS shouting */
.kol-table-cell-title {
  padding: 12px 16px;
  font-family: var(--kol-font-family-mono);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--kol-surface-on-primary);
  white-space: nowrap;
}

.kol-table-cell-text {
  padding: 12px 16px;
  font-family: var(--kol-font-family-mono);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.4;
  color: var(--kol-fg-64);
  white-space: nowrap;
}

.kol-table-cell-meta {
  padding: 12px 16px;
  font-family: var(--kol-font-family-mono);
  font-size: 0.625rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--kol-fg-64);
  white-space: normal;
  min-width: 10rem;
  max-width: 24rem;
}

.kol-table-cell-meta-strong {
  padding: 12px 16px;
  font-family: var(--kol-font-family-mono);
  font-size: 0.625rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--kol-surface-on-primary);
  white-space: normal;
  min-width: 10rem;
}

/* Content classes — no padding, used inside cells */

.kol-table-meta {
  font-family: var(--kol-font-family-mono);
  font-size: 0.625rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--kol-fg-64);
  white-space: normal;
  max-width: 24rem;
}

.kol-table-meta-strong {
  font-family: var(--kol-font-family-mono);
  font-size: 0.625rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--kol-surface-on-primary);
  white-space: normal;
}

.kol-table-pair {
  min-width: 18rem;
}

.kol-table-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 2px 12px;
  border-radius: 9999px;
  font-family: var(--kol-font-family-mono);
  font-size: 0.75rem;
  font-weight: 400;
  white-space: nowrap;
}

.kol-table-pill-light { background-color: var(--kol-surface-secondary); color: var(--kol-surface-on-secondary); }
.kol-table-pill-muted { background-color: var(--kol-fg-16); color: var(--kol-surface-on-primary); }
.kol-table-pill-dark  { background-color: var(--kol-surface-on-primary); color: var(--kol-surface-primary); }

.kol-table-token {
  /* THE LOOK LIVES IN ONE PLACE (2026-08-09) — the shared chip recipe in
   * kol-type-roles.css (`.kol-prose code, .kol-doc-code-inline,
   * .kol-table-token`): font, size, weight, colour, fill, padding, radius.
   * This rule keeps only the CELL mechanics the prose chip must not have. */
  display: inline-flex;
  align-items: center;
  /* No outer margin: spacing is the CONTAINER's job. The margin here
   * double-spaced against every flex row's own gap, which is the ragged
   * rhythm the metadata rows showed. */
  line-height: 1;
  white-space: nowrap;
}

.kol-table-wrapper.kol-table--simple { border: none; border-radius: 0; }
.kol-table-wrapper.kol-table--simple .kol-table-thead { background: none; border-bottom: 1px solid var(--kol-fg-12); }
.kol-table-wrapper.kol-table--simple .kol-table-row   { border-bottom: 1px solid var(--kol-fg-08); }
/* compact — record-surface density (2026-08-09): tighter cell box for the
 * RecordManager table; the reference's rows sit near half the default. */
.kol-table-wrapper.kol-table--compact .kol-table th,
.kol-table-wrapper.kol-table--compact .kol-table td { padding: 0.5rem 0.75rem; }

.kol-table-wrapper.kol-table--simple .kol-table th,
.kol-table-wrapper.kol-table--simple .kol-table td { border-right: none; }
.kol-table-wrapper.kol-table--simple .kol-table th:first-child,
.kol-table-wrapper.kol-table--simple .kol-table td:first-child { padding-inline-start: 0; }
.kol-table-wrapper.kol-table--simple .kol-table th:last-child,
.kol-table-wrapper.kol-table--simple .kol-table td:last-child { padding-inline-end: 0; }

.kol-table th,
/* oq, not fg — alpha verticals brightened over the thead's fg-04 tint while
 * the (already-converted) horizontals stayed flat. The fourth seam of the
 * 2026-07-15 chess-audit finding 4; the first three were converted then. */
.kol-table td { border-right: 1px solid var(--kol-oq-08); }
.kol-table th:last-child,
.kol-table td:last-child { border-right: none; }

/* `.kol-table code` — the THIRD spelling of the inline chip, found and folded
 * 2026-08-09 (an off-scale font size and a bare radius literal). A bare
 * <code> in a cell now takes the ONE recipe in kol-type-roles.css beside
 * .kol-doc-code-inline and .kol-table-token. */

.kol-table a {
  color: var(--kol-link);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

.kol-table a:hover { color: var(--kol-link-hover); }

@media (max-width: 768px) {
  .kol-table-cell-title,
  .kol-table-cell-text,
  .kol-table-cell-meta,
  .kol-table-cell-meta-strong { padding: 8px 12px; }
}

@media (max-width: 480px) {
  .kol-table-cell-title,
  .kol-table-cell-text,
  .kol-table-cell-meta,
  .kol-table-cell-meta-strong {
    font-size: 0.65rem;
    padding: 6px 10px;
  }
}

/*
 * ─────────────────────────────────────────────────────────────────────
 * FeatureSplit — src/components/organisms/FeatureSplit.jsx
 * ─────────────────────────────────────────────────────────────────────
 *
 * Destined for kol-components-organisms.css.
 *
 * Structural (applied by FeatureSplit.jsx; do not use directly):
 *   .kol-feature-split                  section — surface bg + ink
 *   .kol-feature-split-kicker           mono eyebrow, accent color
 *   .kol-feature-split-pull             display pull headline
 *   .kol-feature-split-pull em          italic accent inside the pull
 *   .kol-feature-split-body             lede paragraph, 72% ink
 *   .kol-feature-split-meta             stats strip — hairline top border
 *   .kol-feature-split-meta-num         stat number
 *   .kol-feature-split-meta-label       stat label — mono, 48% ink
 *   .kol-feature-split-visual img       cover-fit media
 *   .kol-feature-split-visual-veil      bottom gradient (caption legibility)
 *   .kol-feature-split-visual-caption   mono caption over the media
 *
 * Port notes (from apps/brand kol-site.css `.site-feature*`):
 *   - text-transform: uppercase DROPPED from kicker / meta-label / caption —
 *     KOL rule: author casing at the call site.
 *   - Hardcoded "Right Grotesk" / "Right Grotesk Text" / "Right Grotesk Wide"
 *     families → var(--kol-font-family-sans) (this theme tokenizes only
 *     sans / sans-narrow / sans-compact; no Text/Wide tokens).
 *   - App `--kol-pad-page-*` padding and the shared `.site-*` full-bleed
 *     rule moved to Tailwind utilities in the JSX (`fullBleed` prop).
 */

/* =============================================================================
 * SectionSplit + SectionText (the section family, SectionSet 2026-08-26)
 *
 * `.kol-section-text-{label,pull,body}` are the text block's classes and
 * `.kol-section-split-*` the split's; every `.kol-feature-split-*` selector
 * below is the same rule under the old name, kept ONE release for a consumer's
 * own CSS still pointing at it — dropped at the next major.
 * ============================================================================= */

.kol-feature-split,
.kol-section-split {
  background: var(--kol-surface-primary);
  color: var(--kol-surface-on-primary);
}

/* THE EYEBROW IS UPPERCASE BY ROLE (user ruling 2026-08-26, the fourth time).
 * Casing is a property of the ROLE, not a law about strings: an eyebrow /
 * kicker / section label is caps by design language — the display voice
 * already carries its transform "by contract" — while body copy, buttons and
 * tags render as authored. SectionText stamps this on every label it renders,
 * whatever voice class rides beside it. The old "no text-transform, ever" was
 * one call about button strings written up as a law for every string. */
.kol-section-text-eyebrow,
/* the caps role for a HEADLINE — the split hero's title card (2026-08-26) */
.kol-section-text-caps {
  text-transform: uppercase;
}

/* .kol-section-text-label — RETIRED 0.57.1 (SectionTextLabelVoice): the
 * family's label wears the hero's helper-12 / meta voice now, as utilities on
 * the element; this mono-18 accent kicker paints only a consumer's own
 * `.kol-feature-split-kicker` until the next major. */
.kol-feature-split-kicker {
  font-family: var(--kol-font-family-mono, monospace);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--kol-accent-primary);
}

.kol-feature-split-pull,
/* headlines BALANCE (WorkListingRowsAndFilters, 2026-08-27 — user: "don't leave
 * one word, it's tacky"): no orphaned last word on any SectionText headline. */
.kol-section-text-headline {
  text-wrap: balance;
}

.kol-section-text-pull {
  margin: 0;
  font-family: var(--kol-font-family-sans);
  font-weight: 700;
  font-size: clamp(40px, 5.5vw, 72px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--kol-surface-on-primary);
}

.kol-feature-split-pull em,
.kol-section-text-pull em {
  font-family: var(--kol-font-family-sans);
  font-feature-settings: "liga", "dlig";
  font-weight: 700;
  font-style: italic;
  color: var(--kol-accent-primary);
}

/* the section family's body voice is MONO (SectionTextBodyMono, kol-website
 * 2026-08-27 — user: "I don't want the sans anywhere, I want the text on the
 * cards to default mono, with props to change it if I feel like it"). Was
 * sans 16 / 1.6; now the mono-16 rung (16 / 22) — the section scale, where the
 * Stack hero's lede already sat. Sans is opt-in through `bodyClass` /
 * `slotClass`. The 72% ink is unchanged. */
.kol-feature-split-body,
.kol-section-text-body {
  margin: 0;
  font-family: var(--kol-font-family-mono);
  font-weight: 400;
  font-size: 16px;
  line-height: 22px;
  color: color-mix(in srgb, var(--kol-surface-on-primary) 72%, transparent);
}

.kol-feature-split-meta,
.kol-section-split-meta {
  border-top: 1px solid color-mix(in srgb, var(--kol-surface-on-primary) 8%, transparent);
}

.kol-feature-split-meta-num,
.kol-section-split-meta-num {
  font-family: var(--kol-font-family-sans);
  font-weight: 900;
  font-size: 32px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--kol-surface-on-primary);
}

.kol-feature-split-meta-label,
.kol-section-split-meta-label {
  font-family: var(--kol-font-family-mono, monospace);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: color-mix(in srgb, var(--kol-surface-on-primary) 48%, transparent);
}

.kol-feature-split-visual img,
.kol-section-split-visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}


.kol-feature-split-visual-veil,
.kol-section-split-visual-veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    transparent 0%,
    transparent 60%,
    color-mix(in srgb, var(--kol-surface-primary) 48%, transparent) 100%
  );
  pointer-events: none;
}

.kol-feature-split-visual-caption,
.kol-section-split-visual-caption {
  position: absolute;
  left: 24px;
  bottom: 24px;
  font-family: var(--kol-font-family-mono, monospace);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: color-mix(in srgb, var(--kol-surface-on-primary) 80%, transparent);
}

/*
 * ─────────────────────────────────────────────────────────────────────
 * FullBleedHero — src/components/organisms/FullBleedHero.jsx
 * ─────────────────────────────────────────────────────────────────────
 *
 * Destined for kol-components-organisms.css.
 *
 * Structural (applied by FullBleedHero.jsx; do not use directly):
 *   .kol-full-bleed-hero          section root — surface bg behind the media
 *   .kol-full-bleed-hero-media    cover-fit media layer (Image / HlsVideo /
 *                                 plain <video> / caller-supplied node)
 *
 * Why CSS and not Tailwind for the media layer: the Image molecule bakes
 * `max-w-full h-auto` into every <img>; an inline `h-full` utility can't
 * reliably out-cascade `h-auto` (same utilities layer — stylesheet order,
 * not class order, decides). This unlayered rule wins over Tailwind's
 * layered utilities and pins cover-fill identically for img, video, and
 * caller-supplied media nodes.
 */

/* =============================================================================
 * FullBleedHero
 * ============================================================================= */

.kol-full-bleed-hero {
  background: var(--kol-surface-primary);
}

.kol-full-bleed-hero-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* The hero's veil (SectionHeroRound2, 2026-08-26) — the bottom-heavy
 * gradient StackHero drew over its media, the same device as the split's
 * caption veil, so text pinned to the foot sits on a graded ground. */
.kol-section-hero-veil {
  background: linear-gradient(
    180deg,
    transparent 0%,
    transparent 40%,
    color-mix(in srgb, var(--kol-surface-primary) 72%, transparent) 100%
  );
  pointer-events: none;
}

/* =============================================================================
 * FeaturedCarousel — src/components/organisms/FeaturedCarousel.jsx
 * =============================================================================
 *
 * Append to packages/theme/kol-components-organisms.css.
 *
 * FeaturedCarousel rebuilds on the shared Carousel *core* — it reuses the
 * `.kol-embla*` chrome verbatim (viewport / container / slide / controls /
 * `.is-slides` wide-slide width), so NONE of that is redefined here. Frame,
 * progress bar, and glass positioning are Tailwind utilities on the JSX.
 *
 * The one rule that can't be a utility: the media layer. The Image molecule
 * bakes `h-auto` (a Tailwind layer utility), so an inline `h-full` can't
 * reliably out-cascade it — the same reason FullBleedHero uses a theme rule.
 * This unlayered rule wins and pins image / video / caller-node media as a
 * cover-fit background over the frame.
 */

.kol-featured-carousel-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* ═══════════════════════════════════════════════════════════════
 * MediaLibrary — organisms/MediaLibrary.jsx
 * The picker card, the tile grid, the tree rows and the path bar.
 * The card width and tile floor were inline literals in the four consumer
 * forks (kol-ds-fxr MediaPicker.jsx:214 and :274) — they are tokens here
 * because geometry is referenced, never re-guessed per consumer.
 * NOT here: the scrim, the centring, Esc/backdrop dismiss and the corner
 * close — FullscreenOverlay (.kol-overlay) already owns all of it.
 * NO elevation. A drop shadow under the modal was smuggled in 2026-08-01
 * and struck out the same day (user ruling) — the scrim is the separation.
 * ═══════════════════════════════════════════════════════════════ */

.kol-media-picker {
  /* The card's resting width. Was 45rem and the ContentFilters header could
   * not fit in it: "10 of 10" wrapped to three lines, the view toggle clipped,
   * and the close button collided with it. The header is the constraint, not
   * the grid. It still shrinks inside .kol-overlay's padding. */
  --kol-media-picker-w: 64rem;
  /* the grid's tile floor — auto-fill packs as many as clear this */
  --kol-media-tile-min: 10rem;

  display: flex;
  flex-direction: column;
  width: var(--kol-media-picker-w);
  max-width: 100%;
  max-height: 85vh;
  /* min-height:0 + the body owning the scroll — the card itself scrolling was
   * what dragged the sticky header out of view. */
  min-height: 0;
  overflow: hidden;
  /* Extra block-start: FullscreenOverlay's close button is absolutely placed
   * on the SHEET corner, so at even padding it landed on top of the view
   * toggle. The card reserves the lane instead of the close moving. */
  padding: var(--kol-spacing-12) var(--kol-spacing-5) var(--kol-spacing-5);
  border: 1px solid var(--kol-oq-08);
  border-radius: var(--kol-radius-sm);
  background: var(--kol-surface-primary);
}

/* The browser is the same body with no card around it — in flow, it takes the
 * width the consumer gives it. Tiles at 260 (MediaLibraryReconcile, kol-r2b2
 * 2026-08-26 — FileList's `minmax(260px, 1fr)`; the picker keeps 10rem
 * because its card is 64rem wide). */
.kol-media-browser {
  display: flex;
  flex-direction: column;
  width: 100%;
  --kol-media-tile-min: 16.25rem;
}

.kol-media-grid {
  display: grid;
  gap: var(--kol-spacing-3);
  grid-template-columns: repeat(auto-fill, minmax(var(--kol-media-tile-min), 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}

.kol-media-list {
  display: flex;
  flex-direction: column;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* One folder row — CLICK-TO-ENTER (MediaLibraryReconcile, 2026-08-26): the
 * row is FileList's — icon box · name · trailing chevron-right over a
 * hairline — and clicking it enters the prefix; the breadcrumb steps back.
 * Finder's disclose-in-place chevron (2026-08-01) is gone, not a variant. */
.kol-media-folder {
  display: flex;
  align-items: center;
  gap: var(--kol-spacing-3);
  padding: var(--kol-spacing-2) var(--kol-spacing-1);
  border-bottom: 1px solid var(--kol-fg-08);
  border-radius: var(--kol-radius-sm);
  cursor: pointer;
  transition: background-color var(--kol-transition-fast);
}

.kol-media-folder:hover {
  background: var(--kol-fg-04);
}

/* The picker's path bar rides the FOOT of its card. */
.kol-media-pathbar {
  display: flex;
  align-items: center;
  gap: var(--kol-spacing-1);
  margin-block-start: auto;
  padding-block-start: var(--kol-spacing-3);
  border-top: 1px solid var(--kol-oq-08);
}

/* The BODY scrolls, never the card — a scrolling card dragged the header out
 * of view, which is what made the picker feel broken. */
.kol-media-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* Thumb — the tile's media box. It is the positioning context for the video
 * fallback below, which is the only reason it carries `position`. */
.kol-media-thumb {
  position: relative;
  width: 100%;
  height: 100%;
}

/* A blank square must never be the resting state (lobby/MediaLibraryVideoFallback,
 * filed from kol-website 2026-08-01, quoting the consumer this replaced).
 *
 * A <video> paints NOTHING until a frame decodes — so on a slow link, or a codec
 * the browser cannot decode at all, a video tile is an empty grey box with no
 * name and no type marker, and the page reads as broken rather than as loading.
 * 222 of the 433 objects in the reference bucket are video/mp4.
 *
 * This is the <img alt> equivalent: a play glyph and the filename, sitting
 * BEHIND the video and revealed only while it has nothing to show. The video
 * covers it the moment a frame lands, so a decoding tile never flashes it.
 *
 * NB the loading strategy is deliberately untouched. The brief probed
 * preload=metadata + #t= against preload=auto + seek and BOTH timed out
 * headless (no h264 decoder), so that test discriminates nothing and no
 * evidence exists either way. The fallback needs no decoder to justify it. */
.kol-media-thumb-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--kol-spacing-2);
  padding-inline: var(--kol-spacing-3);
  text-align: center;
  color: var(--kol-fg-48);
  pointer-events: none;
}

.kol-media-thumb-fallback > span {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Painted — the video has a frame, so the fallback stops being the tile's
 * resting state. Kept in the layout box (opacity, not display) so nothing
 * reflows when the first frame arrives. */
.kol-media-thumb-fallback[data-painted='true'] {
  opacity: 0;
}

/* Sortable header — a real button inside the <th> so it is keyboard-reachable.
 * The glyph is always in the layout box (opacity, not display) so the header
 * does not reflow on first sort. */
.kol-table-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--kol-spacing-1);
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
}

.kol-table-sort:hover { color: var(--kol-surface-on-primary); }
.kol-table-sort svg { opacity: 0.25; transition: opacity var(--kol-transition-fast); }
.kol-table-sort:hover svg { opacity: 0.6; }
[aria-sort] .kol-table-sort svg { opacity: 1; }

/* ─────────────────────────────────────────────────────────────────────
 * ContentFilters — the FIRST group's column (ContentFiltersFirstGroupFixedWidth,
 * kol-monitor 2026-08-27 — user ruling: "nope not hug, fix a size … if columns,
 * maybe just use one?"). ONE CATALOG COLUMN: the `1fr` of `repeat(6, 1fr)` gap
 * 24 — `(width − 5 × 24px) / 6`, a fraction, never a px — so the first group
 * sits over the first card and the flowing groups start over the second. The
 * header row is the CONTAINER (`100cqw`): the count + LIST/GRID strip beside
 * the groups narrows the groups' box, and a `%` measured inside it came out
 * short by the strip + gap. A page without a 6-column catalog (/work, a list)
 * gets the same fraction of its own row, so the number is one everywhere.
 * Components layer — a consumer's `group.className` width utility still wins
 * on the odd page. Overrules the WIDTH of the 0.104.3 hug; by-position stands.
 * ───────────────────────────────────────────────────────────────────── */
.kol-filters-row {
  container-type: inline-size;
}
/* THE TRACK COUNT, MEASURED ONCE AND READ TWICE (CatalogFilterFirstGroupTrackCount,
 * kol-client-olina 2026-09-03). The first group was `(100cqw − 120px) / 6` — one
 * column of a six-track grid — while the catalog grid asks how many tracks FIT
 * (ceiling 6, floor `minColumn`): on a capped page at 1280 the grid renders five
 * at 165 and the group measured 133, its right edge mid-card. The 2026-08-27
 * "sits over the first card" law was only true at six.
 *
 * Both read `--kol-catalog-n`, the count the grid actually renders. CatalogPage
 * MEASURES it (a ResizeObserver on the grid — `min(cols, floor((W + gap) /
 * (min + gap)))`, exactly what `repeat(auto-fill, minmax(…))` resolved to) and
 * publishes it on the page, so six-track pages are pixel-identical and narrower
 * ones agree. Unset — a ContentFilters outside CatalogPage — falls back to 6,
 * the pre-0.137.0 formula.
 *
 * ⚠️ 0.137.0 computed the count HERE with `round(down, (100cqw + 24px) / (min +
 * 24px), 1)`. Chromium resolves a `<length> / <length>` division to a number;
 * Firefox does not, so the declaration was invalid at computed-value time,
 * `repeat(var(--n))` fell to `none`, and every catalog rendered ONE column — a
 * ~1500px card (user: "is this supposed to be a joke? huge card"). Pulled the
 * same hour; the count is measured in JS now, and CSS does one division by a
 * NUMBER, which is Level 3 and everywhere. */
.kol-filters-first {
  flex: none;
  width: calc((100cqw - (var(--kol-catalog-n, 6) - 1) * 24px) / var(--kol-catalog-n, 6));
}


/* ─────────────────────────── LayerStack ───────────────────────────────
 * The layers panel (editor-panels-the-held-specs A1, kol-fxr 2026-09-03).
 * Values are the engine's `.kol-compose-layer-*` rules verbatim, renamed:
 * the DS owns this chrome now, and two owners of one class name is the drift
 * this estate keeps paying for. CSS rather than utilities because the states,
 * the drop indicators (pseudo-elements) and the hover-reveal (a descendant
 * rule off `[data-layer-stack]:hover`) are not expressible as classes on the
 * element.
 * ───────────────────────────────────────────────────────────────────── */

.kol-layer-stack-line {
  display: flex;
  align-items: center;
  gap: 2px;
}
.kol-layer-stack-collapse {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  cursor: pointer;
  color: var(--kol-fg-64);
  padding: 0;
}
.kol-layer-stack-collapse:hover { color: var(--kol-surface-on-primary); }
/* Chevrons are focus chrome, not resting chrome (Figma model): hidden until
   the pointer is inside the stack, then every container row shows its own. */
.kol-layer-stack-collapse { opacity: 0; transition: opacity 120ms; }
[data-layer-stack]:hover .kol-layer-stack-collapse { opacity: 1; }
/* Indent nested rows one chevron slot per level — a child's type icon aligns
   under its parent's icon, not its name. Top-level rows sit flush. */
.kol-layer-stack-nest { padding-left: 16px; }

.kol-layer-stack-row {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  padding: 4px 60px 4px 8px;  /* right padding reserves the two absolutely-
                                 positioned toggle buttons */
  color: var(--kol-fg-64);
  border-radius: 4px;
  cursor: grab;
  position: relative;
}
.kol-layer-stack-row:hover {
  background: var(--kol-fg-04);
  color: var(--kol-surface-on-primary);
}
/* Selected = accent highlight; a selected container also tints its expanded
   children block one shade lighter (Figma model). Hover stays grey. */
.kol-layer-stack-row.is-active {
  background: color-mix(in srgb, var(--kol-accent-primary) 26%, transparent);
  color: var(--kol-fg-emphasis);
}
.kol-layer-stack-row.is-tinted {
  background: color-mix(in srgb, var(--kol-accent-primary) 11%, transparent);
}
/* Hidden layer — dim the icon + name only; the slashed eye stays legible. */
.kol-layer-stack-row.is-hidden .kol-layer-stack-main { opacity: 0.4; }
.kol-layer-stack-row.is-dragging { opacity: 0.4; cursor: grabbing; }
.kol-layer-stack-row[draggable]:active { cursor: grabbing; }

/* Drop indicator — 2px accent line at the top or bottom of the target row. */
.kol-layer-stack-row.is-drop-above::before,
.kol-layer-stack-row.is-drop-below::after {
  content: '';
  position: absolute;
  left: 4px;
  right: 4px;
  height: 2px;
  background: var(--kol-accent-primary);
  pointer-events: none;
  z-index: 1;
}
.kol-layer-stack-row.is-drop-above::before { top: -1px; }
.kol-layer-stack-row.is-drop-below::after  { bottom: -1px; }

.kol-layer-stack-main {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: none;
  cursor: pointer;
  color: inherit;
  padding: 0;
  text-align: left;
}
.kol-layer-stack-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

/* The eye and the lock: absolute in the row's reserved right padding, hidden
   until the row is hovered, PINNED visible when the layer is hidden / locked
   or the row is active (`.is-pinned`), so a toggled state is never a secret. */
.kol-layer-stack-toggle {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  border-radius: 4px;
  padding: 0;
  cursor: pointer;
  color: var(--kol-oq-48);
  opacity: 0;
  transition: opacity 120ms;
}
.kol-layer-stack-toggle--eye  { right: 28px; }
.kol-layer-stack-toggle--lock { right: 0; }
.kol-layer-stack-row:hover .kol-layer-stack-toggle,
.kol-layer-stack-toggle.is-pinned { opacity: 1; }
.kol-layer-stack-toggle:hover { color: var(--kol-fg-emphasis); background: var(--kol-fg-08); }
.kol-layer-stack-toggle.is-on { color: var(--kol-accent-primary); }

/* ── ColumnBrowser · the mobile four-zone row ──────────────────────────
 * ColumnBrowserMobileViews §1 (kol-r2b2, 2026-09-03). Height follows zone 2,
 * the 44px thumbnail: 60px, not the DS Table's `12px 16px`, which is right for
 * a 14px glyph and three times too airy for a thumbnail. The divider starts at
 * ZONE 3's left edge — 14 disclosure + 8 gap + 44 icon + 8 gap = 74 — which is
 * what both references draw and what a utility cannot express, since it is a
 * pseudo-element inset on a sibling boundary.
 * ─────────────────────────────────────────────────────────────────────── */
.kol-column-browser-row--zones {
  min-height: 60px;
  position: relative;
}
.kol-column-browser-row--zones + .kol-column-browser-row--zones::before {
  content: '';
  position: absolute;
  top: 0;
  left: 74px;   /* zone 3's left edge */
  right: 0;
  height: 1px;
  background: var(--kol-oq-08);
  pointer-events: none;
}
/* the thumbnail fills its box and crops — a media tile is the image, not a
   letterboxed one */
.kol-column-browser-thumb img,
.kol-column-browser-thumb video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ── ColumnBrowser · the mobile grid (item 14) ─────────────────────────
 * 3-up below `md`. For a media bucket the thumbnail IS the tile, so the box is
 * square and the name sits under it; counts, not dates (§2). */
.kol-column-browser-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--kol-spacing-3);
  padding: var(--kol-spacing-3);
}
.kol-column-browser-tile {
  display: flex;
  flex-direction: column;
  gap: var(--kol-spacing-1);
  min-width: 0;
  cursor: pointer;
  background: transparent;
  border: none;
  padding: 0;
  text-align: left;
}
.kol-column-browser-tile-box {
  aspect-ratio: 1;
  border-radius: 5px;
  background: var(--kol-oq-04);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.kol-column-browser-tile-box img,
.kol-column-browser-tile-box video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.kol-column-browser-tile.is-selected .kol-column-browser-tile-box {
  outline: 2px solid var(--kol-accent-primary);
  outline-offset: 1px;
}
