/* ==========================================================================
   ICL Design System — Components
   --------------------------------------------------------------------------
   Requires tokens/tokens.css (and optionally tokens/themes.css).
   Components reference ONLY semantic tokens (--icl-color-*, --icl-space-*).
   Naming: .icl-component, .icl-component--variant, .icl-component__part
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · Reset & base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchor jumps clear the sticky .icl-navbar instead of hiding the target
     heading behind it (navbar is 3.5rem + keyline; a little breathing room). */
  scroll-padding-top: 4.5rem;
}

body {
  margin: 0;
  font-family: var(--icl-font-sans);
  font-size: var(--icl-text-md);
  line-height: var(--icl-leading-normal);
  color: var(--icl-color-text);
  background: var(--icl-color-bg);
  -webkit-font-smoothing: antialiased;
}

img, svg, video { max-width: 100%; height: auto; display: block; }

:focus-visible {
  outline: 2px solid var(--icl-color-focus-ring);
  outline-offset: 2px;
}

::selection {
  background: var(--icl-color-accent);
  color: var(--icl-color-on-accent);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   2 · Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
  margin: 0 0 var(--icl-space-3);
  font-family: var(--icl-font-sans);
  font-weight: 700;
  line-height: var(--icl-leading-tight);
  color: var(--icl-color-heading);
}

h1 { font-size: var(--icl-text-4xl); }
h2 { font-size: var(--icl-text-3xl); }
h3 { font-size: var(--icl-text-2xl); }
h4 { font-size: var(--icl-text-xl); }
h5 { font-size: var(--icl-text-lg); }
h6 {
  font-size: var(--icl-text-sm);
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-caps);
  color: var(--icl-color-text-muted);
}

p { margin: 0 0 var(--icl-space-4); }

a {
  color: var(--icl-color-link);
  text-decoration: none;
  text-underline-offset: 0.2em;
  transition: color var(--icl-duration-fast) var(--icl-ease);
}
a:hover { color: var(--icl-color-link-hover); text-decoration: underline; }

hr {
  border: 0;
  border-top: 1px solid var(--icl-color-border);
  margin: var(--icl-space-6) 0;
}

code, kbd, samp {
  font-family: var(--icl-font-mono);
  font-size: 0.875em;
}
code {
  background: var(--icl-color-surface-sunken);
  border: 1px solid var(--icl-color-border);
  border-radius: var(--icl-radius-sm);
  padding: 0.1em 0.35em;
}
/* On dark bands the light chip disappears under light text — use the
   accent as the highlight instead (theme-aware). */
.icl-section--inverse code,
.icl-hero code,
.icl-footer code {
  background: var(--icl-color-accent);
  border-color: transparent;
  color: var(--icl-color-on-accent);
}

blockquote {
  margin: var(--icl-space-5) 0;
  padding: var(--icl-space-2) var(--icl-space-5);
  border-left: var(--icl-keyline-width) solid var(--icl-color-keyline);
  font-family: var(--icl-font-serif);
  font-size: var(--icl-text-lg);
  line-height: var(--icl-leading-loose);
  color: var(--icl-color-text-muted);
}

/* Display type — Rift. The distinct ICL voice: condensed, uppercase. */
.icl-display {
  font-family: var(--icl-font-display);
  font-weight: 700;
  font-size: var(--icl-text-display);
  line-height: 1.02;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--icl-color-heading);
  margin: 0 0 var(--icl-space-3);
}

.icl-display--md { font-size: var(--icl-text-5xl); }
.icl-display--sm { font-size: var(--icl-text-4xl); }

/* Eyebrow — small tracked label above a heading. Proxima Nova caps;
   Globe blue on light surfaces (default theme), project accent under
   project themes. */
.icl-eyebrow {
  display: block;
  font-family: var(--icl-font-sans);
  font-weight: 700;
  font-size: var(--icl-text-sm);
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-caps);
  color: var(--icl-color-eyebrow);
  margin: 0 0 var(--icl-space-2);
}

/* Signature name style — first name Merriweather bold, last name
   Proxima Nova caps (from the PAPI team grid). Works inline anywhere:
   <span class="icl-name__first">Jack</span>
   <span class="icl-name__last">Dongarra</span> */
.icl-name__first {
  font-family: var(--icl-font-serif);
  font-weight: 700;
}
.icl-name__last {
  font-family: var(--icl-font-sans);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.045em;
}

/* Lede — opening paragraph */
.icl-lede {
  font-size: var(--icl-text-xl);
  line-height: var(--icl-leading-snug);
  color: var(--icl-color-text-muted);
  max-width: 42em;
}

/* Prose — long-form editorial (newsletter, articles) */
.icl-prose {
  font-family: var(--icl-font-serif);
  font-size: 1.0625rem;
  line-height: var(--icl-leading-loose);
  max-width: var(--icl-container-narrow);
}
.icl-prose h2, .icl-prose h3 { font-family: var(--icl-font-sans); margin-top: var(--icl-space-6); }

/* --------------------------------------------------------------------------
   3 · Layout
   -------------------------------------------------------------------------- */
.icl-container {
  max-width: var(--icl-container-max);
  margin-inline: auto;
  padding-inline: var(--icl-container-pad);
}
.icl-container--narrow { max-width: var(--icl-container-narrow); }

.icl-section { padding-block: var(--icl-space-8); }
.icl-section--tight { padding-block: var(--icl-space-7); }

/* Alternating band backgrounds (the projector-site rhythm) */
.icl-section--sunken {
  background: var(--icl-color-surface-sunken);
  border-top: 1px solid var(--icl-color-border);
  border-bottom: 1px solid var(--icl-color-border);
  box-shadow: var(--icl-shadow-inset-band);
}
.icl-section--inverse {
  background: var(--icl-color-inverse-bg);
  color: var(--icl-color-inverse-text);
}
.icl-section--inverse h1, .icl-section--inverse h2, .icl-section--inverse h3,
.icl-section--inverse h4, .icl-section--inverse .icl-display {
  color: var(--icl-color-inverse-heading);
}
.icl-section--inverse a:not([class*="icl-btn"]) { color: var(--icl-color-inverse-link); }
.icl-section--inverse .icl-eyebrow { color: var(--icl-color-eyebrow-inverse); }

/* Accent band — the band-level accent surface: Tennessee Orange at lab level,
   each project theme its own hue (rule 8 satisfied through the accent slot).
   Adopted with the hero background suite (v0.7). On-accent ink carries all
   text: the usual eyebrow hue (pure accent) and link hue (Globe blue) both
   fail against the accent itself — accent-on-accent is invisible and Globe
   blue is 2.4:1 on orange — so both drop to on-accent here. Keep inline
   links off accent bands where possible; buttons are the CTA vocabulary. */
.icl-section--accent {
  background: var(--icl-color-accent);
  color: var(--icl-color-on-accent);
}
/* Accent-filled buttons sitting on the accent band match the band — a white
   outline gives them back an edge. */
.icl-section--accent .icl-btn--primary,
.icl-section--accent .icl-btn--download {
  border-color: var(--icl-color-on-emphasis);
}
/* Secondary (outline) buttons drop to on-accent — their accent-strong
   text/border would sink into the band. Border follows via currentColor. */
.icl-section--accent .icl-btn--secondary { color: var(--icl-color-on-accent); }
.icl-section--accent h1, .icl-section--accent h2, .icl-section--accent h3,
.icl-section--accent h4, .icl-section--accent .icl-display {
  color: var(--icl-color-on-accent);
}
.icl-section--accent a:not([class*="icl-btn"]) { color: var(--icl-color-on-accent); }
.icl-section--accent .icl-eyebrow { color: var(--icl-color-on-accent); }
.icl-section--accent.icl-background-fx { --icl-grid-fade: var(--icl-color-accent); }

/* Signature background effect (.icl-background-fx) — descendant of the legacy
   grid-bg.jpg, built in pure CSS + SVG. It's adaptive: horizontal scanlines
   on light surfaces, the crossed graph-paper grid on dark stone bands. One
   class, .icl-background-fx;
   the band's own light/dark treatment picks the pattern (David's call —
   scanlines read best on limestone, the grid reads best light-on-stone).
   In both cases the lines fade in and out over ~1.8px (printed, not
   pixel-crisp) with an SVG film-grain wash so the surface reads as worn
   paper.

   The veil fades the texture out around the content so headings can
   breathe. Default assumes the heading sits upper-left: clean at the top
   left, texture emerging toward the bottom right. For bands with centered
   content, .icl-background-fx--center clears the middle instead. Override
   --icl-grid-veil for anything bespoke. */
.icl-background-fx {
  /* Light bands: warm limestone scanlines. Multiply lays the lines down
     like ink on the surface so they take the limestone's warmth instead
     of sitting on top as gray; veil and grain stay normal. */
  /* The grain SVGs are base64-encoded ON PURPOSE: CSS aggregators (Drupal 7's
     rewrote the SVG-internal filter reference "#g" into a file path, which
     killed the filter and tiled the rect solid black) can't touch base64.
     The rect also carries fill='none' so a failed filter degrades to
     invisible, never black. Decoded source lives in tools/grain-svgs.md.
     (Keep even comments free of literal "u r l (" sequences — aggregator
     regexes don't all strip comments first.) */
  --icl-grid-fade: var(--icl-color-surface-sunken);
  --icl-grid-veil: linear-gradient(to top left, transparent 10%, var(--icl-grid-fade) 80%);
  /* Grain rides in a custom property so a band can opt out inline
     (--icl-fx-grain: none) — e.g. on a pure-white band where the wash
     reads as off-white. */
  --icl-fx-grain: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxNDAnIGhlaWdodD0nMTQwJz48ZmlsdGVyIGlkPSdnJz48ZmVUdXJidWxlbmNlIHR5cGU9J2ZyYWN0YWxOb2lzZScgYmFzZUZyZXF1ZW5jeT0nMC44JyBudW1PY3RhdmVzPScyJyBzdGl0Y2hUaWxlcz0nc3RpdGNoJy8+PGZlQ29sb3JNYXRyaXggdmFsdWVzPScwIDAgMCAwIDAuMjIgMCAwIDAgMCAwLjE5IDAgMCAwIDAgMC4xNCAwIDAgMCAwLjEyIDAnLz48L2ZpbHRlcj48cmVjdCB3aWR0aD0nMTQwJyBoZWlnaHQ9JzE0MCcgZmlsbD0nbm9uZScgZmlsdGVyPSd1cmwoI2cpJy8+PC9zdmc+");
  background-image:
    var(--icl-grid-veil),
    var(--icl-fx-grain),
    linear-gradient(180deg, transparent 0.2px, var(--icl-color-scanline) 0.9px, transparent 1.8px);
  background-size:
    100% 100%,
    140px 140px,
    var(--icl-scanline-size) var(--icl-scanline-size);
  background-blend-mode: normal, normal, multiply;
}
.icl-section--inverse.icl-background-fx,
.icl-hero.icl-background-fx,
.icl-footer.icl-background-fx,
.icl-background-fx--inverse {
  /* Dark stone bands: light graph-paper grid. White lines would vanish
     under multiply, so these composite normally. */
  --icl-grid-fade: var(--icl-color-inverse-bg);
  --icl-fx-grain: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxNDAnIGhlaWdodD0nMTQwJz48ZmlsdGVyIGlkPSdnJz48ZmVUdXJidWxlbmNlIHR5cGU9J2ZyYWN0YWxOb2lzZScgYmFzZUZyZXF1ZW5jeT0nMC44JyBudW1PY3RhdmVzPScyJyBzdGl0Y2hUaWxlcz0nc3RpdGNoJy8+PGZlQ29sb3JNYXRyaXggdmFsdWVzPScwIDAgMCAwIDEgMCAwIDAgMCAxIDAgMCAwIDAgMC45NSAwIDAgMCAwLjEgMCcvPjwvZmlsdGVyPjxyZWN0IHdpZHRoPScxNDAnIGhlaWdodD0nMTQwJyBmaWxsPSdub25lJyBmaWx0ZXI9J3VybCgjZyknLz48L3N2Zz4=");
  background-image:
    var(--icl-grid-veil),
    var(--icl-fx-grain),
    linear-gradient(180deg, transparent 0.2px, var(--icl-color-inverse-grid-line) 0.9px, transparent 1.8px),
    linear-gradient(90deg, transparent 0.2px, var(--icl-color-inverse-grid-line) 0.9px, transparent 1.8px);
  background-size:
    100% 100%,
    140px 140px,
    var(--icl-grid-size) var(--icl-grid-size),
    var(--icl-grid-size) var(--icl-grid-size);
  background-blend-mode: normal;
}
/* Centered-content bands: clear the middle, texture at the edges */
.icl-background-fx--center {
  --icl-grid-veil: radial-gradient(ellipse at 50% 50%, var(--icl-grid-fade) 25%, transparent 85%);
}
/* Spotlight: the inverse veil — the effect is fullest at a focal point and
   fades away from it (e.g. scanlines strongest behind a collage's images).
   Set the focal point with --icl-fx-focus (default sits left-of-center, over
   a collage's media column) and the reach with --icl-fx-spotlight (ellipse
   radii as % of band width/height — the default's 40% vertical radius fades
   the effect out by the top/bottom of a collage's photos rather than running
   to the band edges). */
.icl-background-fx--spotlight {
  --icl-grid-veil: radial-gradient(ellipse var(--icl-fx-spotlight, 55% 40%) at var(--icl-fx-focus, 30% 50%),
    transparent 30%, var(--icl-grid-fade) 100%);
}

/* Hero background suite (.icl-hero-bg) — layered promotional surfaces in the
   manner of the ACS NUCL fx panels: base color → photo → content, with the
   signature effect still supplied by .icl-background-fx (the band's own
   light/dark treatment keeps picking scanlines vs grid — rule 10 intact).
   This class only adds the photo-layer machinery on the band's pseudos.

     <section class="icl-hero icl-background-fx icl-hero-bg"
              style="--icl-hero-image: url('server-room.jpg')">

   Surfaces are the band classes already in the system: .icl-hero /
   .icl-section--inverse (dark stone), .icl-section--sunken (light
   limestone), .icl-section--accent (orange, or the project hue).

   The photo anchors right and masks out toward the content side, so it
   cross-fades against the pattern and the heading sits on calm base color
   (the same reasoning as the ACS --bg-image layer). Knobs:
     --icl-hero-image     the photo; omit it and the band is a plain fx band.
                          Use a site-root-relative or absolute URL — browsers
                          resolve a relative url() in a custom property
                          against the consuming stylesheet, not the page
     --icl-hero-position  cover anchor (default 75% 50%)
     --icl-hero-mask      the cross-fade (overrides the width-adaptive
                          default at every size)
     --icl-hero-overlay-mask  reach of the pattern overlay that rides OVER
                          the photo (default fades in from the content side
                          and holds the photo side; see below)
     --icl-hero-halo      size of the text halo (band-colored bloom behind
                          hero text) — 0 disables (the opt-out), 0.4 default
     --icl-hero-halo-spread   reach of the halo's outer layers (default 2)
     --icl-hero-halo-opacity  strength of the halo color, 0–1 (default 1)
     --icl-hero-overlay-blend  blend of that overlay. Defaults are the
                          adaptive pair (David, 2026-08-21): color-burn on
                          light bands, color-dodge on dark stone — the
                          escape hatch for a tonally mismatched photo is
                          setting this to multiply (light) / screen (dark)
                          inline on the band

   The suite is width-adaptive (David, 2026-08-21): the band is a size query
   container, and the pseudos — which CAN query their originating element —
   step up at 48rem of container width, where a panel stops being a card and
   starts being a hero. Wide panels get feature-strength line inks and the
   long eased cross-fade; card-scale panels keep the quiet default inks and
   a compressed fade so the copy clears the photo. Browsers without
   container queries degrade to the quiet card treatment everywhere — never
   the loud one. The band's OWN fx pattern cannot self-query, so it stays at
   the quiet shared inks at every size; the veil and the photo cover nearly
   all of it, and the overlay is what carries the pattern at feature
   strength. */
.icl-hero-bg {
  position: relative;
  isolation: isolate;  /* keeps the duotone blend inside the band */
  container-name: icl-hero-bg;
  container-type: inline-size;
}
/* z-index -1 paints the pseudos above the band's own background stack
   (base color + fx pattern) but below its in-flow content, so the content
   needs no z-index of its own. Mask blacks are alpha carriers, not rendered
   color. */
/* --icl-hero-fade / --icl-hero-overlay-fade are the width-adaptive default
   masks (internal — override the public knobs above, not these). */
.icl-hero-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image: var(--icl-hero-image, none);
  background-size: cover;
  background-position: var(--icl-hero-position, 75% 50%);
  --icl-hero-fade: linear-gradient(to left, rgba(0,0,0,1) 18%, rgba(0,0,0,0.7) 32%, rgba(0,0,0,0.3) 48%, rgba(0,0,0,0) 64%);
  -webkit-mask-image: var(--icl-hero-mask, var(--icl-hero-fade));
  mask-image: var(--icl-hero-mask, var(--icl-hero-fade));
}
/* Pattern overlay — the signature lines carried OVER the photo. The band's
   own fx pattern sits under the photo and would die where the image is
   opaque; this pseudo re-draws just the line layer above it, masked to
   fade in from the content side and hold the photo side, so the print
   runs across the whole panel. Blends are the adaptive contrast pair,
   chosen over multiply/screen in the 2026-08-21 comparison: ink scanlines
   COLOR-BURN on light bands (etched into the image's darks, clear of its
   highlights); the light grid COLOR-DODGES on dark stone (lit out of the
   image's highlights, absent from its blacks). The texture keys itself to
   the image — strongest where the photo's tonality matches the band, gone
   where it doesn't. For a mismatched photo (dark image on a light band or
   the reverse) the pattern fades out of the overlay region entirely; if it
   must read there, drop --icl-hero-overlay-blend to the even-handed
   multiply (light) / screen (dark). */
.icl-hero-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image:
    linear-gradient(180deg, transparent 0.2px, var(--icl-color-scanline) 0.9px, transparent 1.8px);
  background-size: var(--icl-scanline-size) var(--icl-scanline-size);
  mix-blend-mode: var(--icl-hero-overlay-blend, color-burn);
  --icl-hero-overlay-fade: linear-gradient(to right, rgba(0,0,0,0) 18%, rgba(0,0,0,1) 58%);
  -webkit-mask-image: var(--icl-hero-overlay-mask, var(--icl-hero-overlay-fade));
  mask-image: var(--icl-hero-overlay-mask, var(--icl-hero-overlay-fade));
}
.icl-section--inverse.icl-hero-bg::after,
.icl-hero.icl-hero-bg::after,
.icl-footer.icl-hero-bg::after,
.icl-background-fx--inverse.icl-hero-bg::after {
  background-image:
    linear-gradient(180deg, transparent 0.2px, var(--icl-color-inverse-grid-line) 0.9px, transparent 1.8px),
    linear-gradient(90deg, transparent 0.2px, var(--icl-color-inverse-grid-line) 0.9px, transparent 1.8px);
  background-size:
    var(--icl-grid-size) var(--icl-grid-size),
    var(--icl-grid-size) var(--icl-grid-size);
  mix-blend-mode: var(--icl-hero-overlay-blend, color-dodge);
}
/* Flipped composition — photo holds the left edge, content sits right */
.icl-hero-bg--flip::before {
  background-position: var(--icl-hero-position, 25% 50%);
  --icl-hero-fade: linear-gradient(to right, rgba(0,0,0,1) 18%, rgba(0,0,0,0.7) 32%, rgba(0,0,0,0.3) 48%, rgba(0,0,0,0) 64%);
}
.icl-hero-bg--flip::after {
  --icl-hero-overlay-fade: linear-gradient(to left, rgba(0,0,0,0) 18%, rgba(0,0,0,1) 58%);
}

/* Hero scale (container ≥ 48rem): feature-strength inks on the overlay and
   the long eased cross-fade on the photo. */
@container icl-hero-bg (min-width: 48rem) {
  .icl-hero-bg::before {
    --icl-hero-fade: linear-gradient(to left, rgba(0,0,0,1) 30%, rgba(0,0,0,0.72) 45%, rgba(0,0,0,0.35) 62%, rgba(0,0,0,0) 80%);
  }
  .icl-hero-bg--flip::before {
    --icl-hero-fade: linear-gradient(to right, rgba(0,0,0,1) 30%, rgba(0,0,0,0.72) 45%, rgba(0,0,0,0.35) 62%, rgba(0,0,0,0) 80%);
  }
  .icl-hero-bg::after {
    --icl-color-scanline: var(--icl-color-scanline-strong);
    --icl-color-inverse-grid-line: var(--icl-color-inverse-grid-line-strong);
  }
}

/* Duotone photo — the people-photo gradient map at band scale. The grayscale
   photo blends with the surface beneath it (base color + fx pattern — the
   printed lines show through the image), mapping the photo into the band's
   own hue. Adaptive like the fx itself: on light bands the photo multiplies
   down like ink (a [limestone ink → paper] map); on dark stone and accent
   bands it screens up (a [surface → warm white] map — stone gives a warm
   silver print, accent the orange one). Knobs mirror the person duotone:
     --icl-hero-duotone-contrast  midtone spread, pre-blend
     --icl-hero-duotone-paper     endpoint trim — on dark/accent bands <1
                                  warms highlights off pure white; on light
                                  bands >1 lifts the photo's blacks so the
                                  print stays warm dark, never pure black */
.icl-hero-bg--duotone::before {
  filter: grayscale(1)
          contrast(var(--icl-hero-duotone-contrast, 0.9))
          brightness(var(--icl-hero-duotone-paper, 1.2));
  mix-blend-mode: var(--icl-hero-blend, multiply);
}
.icl-section--inverse.icl-hero-bg--duotone,
.icl-hero.icl-hero-bg--duotone,
.icl-footer.icl-hero-bg--duotone,
.icl-background-fx--inverse.icl-hero-bg--duotone,
.icl-section--accent.icl-hero-bg--duotone {
  --icl-hero-blend: screen;
  --icl-hero-duotone-contrast: 1.4;
  --icl-hero-duotone-paper: 0.93;
}

/* Type is part of the hero formula (David, 2026-08-21).
   Titles wear the display voice — Rift, uppercase — sized to the panel by
   the same 48rem container threshold as the rest of the suite: card scale
   below it, hero scale above. A heading that carries .icl-display keeps
   its own explicit scale (real page heroes keep using it).
   Body copy sits over texture and the photo fade, so it runs a step bolder
   and larger than default; ledes keep their own size (already larger) but
   share the weight. :where keeps the lede exclusion at zero specificity. */
.icl-hero-bg h1:not(.icl-display), .icl-hero-bg h2:not(.icl-display),
.icl-hero-bg h3:not(.icl-display), .icl-hero-bg h4:not(.icl-display) {
  font-family: var(--icl-font-display);
  font-weight: 700;
  font-size: var(--icl-text-2xl);
  line-height: 1.05;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  margin-bottom: var(--icl-space-2);
}
.icl-hero-bg p { font-weight: 600; }
.icl-hero-bg p:where(:not(.icl-hero__lede)) { font-size: var(--icl-text-lg); }
/* Light-band hero text runs at the deepest warm ink so limestone and
   accent panels carry equal text weight (David, 2026-08-21) — the default
   heading (limestone-900) and body (gray-800) read a step lighter than the
   accent band's on-accent. --icl-color-ink, not on-accent: themes override
   on-accent (white for dark project accents), which would break a light
   band. Dark stone bands keep their inverse colors. */
.icl-section--sunken.icl-hero-bg { color: var(--icl-color-ink); }
.icl-section--sunken.icl-hero-bg h1, .icl-section--sunken.icl-hero-bg h2,
.icl-section--sunken.icl-hero-bg h3, .icl-section--sunken.icl-hero-bg h4 {
  color: var(--icl-color-ink);
}
/* Text halo — a soft bloom in the band's OWN base color behind hero text
   (David, 2026-08-21). Where copy crosses into the photo the bloom lifts it
   off the image; over the flat band color it is invisible, because it IS
   that color (--icl-grid-fade, resolved per band by the fx rules; falls
   back to transparent = no-op off an fx band). No new color enters the
   system. Knobs (text-shadow itself has no spread or opacity — spread here
   is the reach of the two outer layers, opacity rides in the color):
     --icl-hero-halo          size — scales every blur radius; 0 disables,
                              0.4 default
     --icl-hero-halo-spread   tail reach — scales only the outer layers;
                              2 default
     --icl-hero-halo-opacity  0–1 — fades the bloom color via color-mix
   A raised card sitting on a hero band should set --icl-hero-halo: 0 (the
   band-colored bloom would show against the card's white). */
.icl-hero-bg :is(h1, h2, h3, h4, p, .icl-eyebrow) {
  --icl-hero-halo-color: color-mix(in srgb,
    var(--icl-grid-fade, transparent) calc(var(--icl-hero-halo-opacity, 1) * 100%),
    transparent);
  text-shadow:
    0 0 calc(3px  * var(--icl-hero-halo, 0.4)) var(--icl-hero-halo-color),
    0 0 calc(6px  * var(--icl-hero-halo, 0.4)) var(--icl-hero-halo-color),
    0 0 calc(12px * var(--icl-hero-halo, 0.4) * var(--icl-hero-halo-spread, 2)) var(--icl-hero-halo-color),
    0 0 calc(24px * var(--icl-hero-halo, 0.4) * var(--icl-hero-halo-spread, 2)) var(--icl-hero-halo-color);
}
/* Hero-scale title size. This block must FOLLOW the base title rule above:
   the two tie on specificity, so source order decides which wins inside
   the query — earlier placement would let the card size override this. */
@container icl-hero-bg (min-width: 48rem) {
  .icl-hero-bg h1:not(.icl-display), .icl-hero-bg h2:not(.icl-display),
  .icl-hero-bg h3:not(.icl-display), .icl-hero-bg h4:not(.icl-display) {
    font-size: var(--icl-text-4xl);
  }
}

/* Signature keyline — accent rule on top edge */
.icl-keyline-top { border-top: var(--icl-keyline-width) solid var(--icl-color-keyline); }

/* Simple responsive grid */
.icl-grid { display: grid; gap: var(--icl-space-5); }
.icl-grid--2 { grid-template-columns: repeat(2, 1fr); }
.icl-grid--3 { grid-template-columns: repeat(3, 1fr); }
.icl-grid--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 56rem) {
  .icl-grid--3, .icl-grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 36rem) {
  .icl-grid--2, .icl-grid--3, .icl-grid--4 { grid-template-columns: 1fr; }
}

/* Section header — eyebrow + title + optional lede, used everywhere */
.icl-section-header { margin-bottom: var(--icl-space-6); max-width: 46em; }
.icl-section-header .icl-display, .icl-section-header h2 { margin-bottom: var(--icl-space-2); }

/* --------------------------------------------------------------------------
   4 · Buttons
   -------------------------------------------------------------------------- */
.icl-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--icl-space-2);
  font-family: var(--icl-font-display); /* buttons are actions — display voice */
  font-size: var(--icl-text-md);
  font-weight: 600;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-wide);
  padding: 0.75em 1.5em;
  border: 1px solid transparent;
  border-radius: var(--icl-radius-md); /* subtly rounded */
  cursor: pointer;
  text-decoration: none;
  transition: background var(--icl-duration-fast) var(--icl-ease),
              border-color var(--icl-duration-fast) var(--icl-ease),
              color var(--icl-duration-fast) var(--icl-ease);
}
.icl-btn:hover { text-decoration: none; }

.icl-btn--primary {
  background: var(--icl-color-accent);
  color: var(--icl-color-on-accent);
}
.icl-btn--primary:hover {
  background: var(--icl-color-accent-strong);
  color: var(--icl-color-bg);
}

.icl-btn--secondary {
  background: transparent;
  color: var(--icl-color-accent-strong);
  border-color: currentColor;
}
.icl-btn--secondary:hover {
  background: var(--icl-color-accent-soft);
  color: var(--icl-color-accent-strong);
}

.icl-btn--ghost {
  background: transparent;
  color: var(--icl-color-text);
}
.icl-btn--ghost:hover { background: var(--icl-color-surface-sunken); color: var(--icl-color-heading); }

/* On dark surfaces */
.icl-btn--inverse {
  background: transparent;
  color: var(--icl-color-inverse-heading);
  border-color: var(--icl-color-inverse-border);
}
.icl-btn--inverse:hover { border-color: var(--icl-color-accent-inverse); color: var(--icl-color-accent-inverse); }

/* Neutral outline — a quiet secondary action (e.g. DOI/BibTeX) with no accent
   color, so an accent-filled sibling can carry the emphasis. */
.icl-btn--outline {
  background: transparent;
  color: var(--icl-color-text);
  border-color: var(--icl-color-border-strong);
}
.icl-btn--outline:hover {
  background: var(--icl-color-surface-sunken);
  border-color: var(--icl-color-text-muted);
  color: var(--icl-color-heading);
}

/* Emphasized download CTA — filled, white text, pairs with a download icon.
   On project themes it uses the accent (dark enough for white text). On the
   lab theme Tennessee Orange can't carry white accessibly (2.5:1), so the fill
   falls back to Globe blue there. */
.icl-btn--download {
  background: var(--icl-color-link);
  color: var(--icl-color-on-emphasis);
}
[data-theme]:not([data-theme="icl"]) .icl-btn--download {
  background: var(--icl-color-accent);
  color: var(--icl-color-on-accent);
}
/* Re-assert the text color on hover, or the global a:hover rule recolors it
   dark against the fill. Darken the fill itself via brightness. */
.icl-btn--download:hover {
  filter: brightness(0.93);
  color: var(--icl-color-on-emphasis);
}
[data-theme]:not([data-theme="icl"]) .icl-btn--download:hover {
  color: var(--icl-color-on-accent);
}

.icl-btn--sm { font-size: var(--icl-text-sm); padding: 0.55em 1.1em; }
.icl-btn--lg { font-size: var(--icl-text-lg); padding: 0.85em 1.8em; }

.icl-btn[disabled], .icl-btn--disabled {
  opacity: 0.45;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   5 · Badges & tags
   -------------------------------------------------------------------------- */
.icl-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-family: var(--icl-font-sans); /* Proxima, not Rift — Rift badges read as buttons */
  font-weight: 700; /* the kit has no Proxima 600 */
  font-size: var(--icl-text-xs);
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-wide);
  line-height: 1;
  padding: 0.45em 0.8em;
  border-radius: var(--icl-radius-sm);
  background: var(--icl-color-accent-soft);
  color: var(--icl-color-accent-strong);
}
.icl-badge--solid { background: var(--icl-color-accent); color: var(--icl-color-on-accent); }
.icl-badge--neutral { background: var(--icl-color-surface-sunken); color: var(--icl-color-text-muted); border: 1px solid var(--icl-color-border); }
.icl-badge--info { background: var(--icl-color-info-bg); color: var(--icl-color-info); }
.icl-badge--success { background: var(--icl-color-success-bg); color: var(--icl-color-success); }
.icl-badge--warning { background: var(--icl-color-warning-bg); color: var(--icl-color-warning); }
.icl-badge--danger { background: var(--icl-color-danger-bg); color: var(--icl-color-danger); }

/* Tag — lowercase metadata chip (research areas, keywords) */
.icl-tag {
  display: inline-block;
  font-size: var(--icl-text-sm);
  line-height: 1;
  padding: 0.4em 0.7em;
  border: 1px solid var(--icl-color-border);
  border-radius: var(--icl-radius-full);
  color: var(--icl-color-text-muted);
  background: var(--icl-color-surface);
  text-decoration: none;
}
a.icl-tag:hover {
  border-color: var(--icl-color-accent-strong);
  color: var(--icl-color-accent-strong);
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   6 · Forms
   -------------------------------------------------------------------------- */
.icl-field { margin-bottom: var(--icl-space-4); }

.icl-label {
  display: block;
  font-size: var(--icl-text-sm);
  font-weight: 600;
  color: var(--icl-color-heading);
  margin-bottom: var(--icl-space-1);
}

.icl-hint {
  font-size: var(--icl-text-sm);
  color: var(--icl-color-text-subtle);
  margin-top: var(--icl-space-1);
}

.icl-input, .icl-select, .icl-textarea {
  width: 100%;
  font-family: var(--icl-font-sans);
  font-size: var(--icl-text-md);
  color: var(--icl-color-text);
  background: var(--icl-color-surface);
  border: 1px solid var(--icl-color-border-strong);
  border-radius: var(--icl-radius-sm);
  padding: 0.6em 0.75em;
  transition: border-color var(--icl-duration-fast) var(--icl-ease);
}
.icl-input:focus, .icl-select:focus, .icl-textarea:focus {
  outline: 2px solid var(--icl-color-focus-ring);
  outline-offset: -1px;
  border-color: var(--icl-color-focus-ring);
}
.icl-input[aria-invalid="true"] { border-color: var(--icl-color-danger); }
.icl-textarea { min-height: 6.5rem; resize: vertical; }

.icl-select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2358595B' d='M1.4 0L6 4.6 10.6 0 12 1.4l-6 6-6-6z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75em center;
  padding-right: 2.25em;
}

/* Search — nav-embedded variant */
.icl-search { position: relative; }
.icl-search .icl-input { padding-left: 2.4em; }
.icl-search::before {
  content: "";
  position: absolute;
  left: 0.8em; top: 50%;
  width: 1em; height: 1em;
  transform: translateY(-50%);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23838588' stroke-width='2'%3E%3Ccircle cx='7' cy='7' r='5'/%3E%3Cpath d='M11 11l4 4'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* --------------------------------------------------------------------------
   7 · Cards
   -------------------------------------------------------------------------- */
.icl-card {
  background: var(--icl-color-surface-raised);
  border: 1px solid var(--icl-color-border);
  border-radius: var(--icl-radius-md);
  padding: var(--icl-space-5);
  box-shadow: var(--icl-shadow-sm);
}

/* Feature card — the keyline motif carries project identity.
   Keyline surfaces are square: a rounded corner would peel away from the
   straight accent edge (same rule on .icl-pub, .icl-alert, .icl-codeblock). */
.icl-card--feature {
  border-top: var(--icl-keyline-width) solid var(--icl-color-keyline);
  border-radius: 0;
  transition: box-shadow var(--icl-duration-base) var(--icl-ease),
              transform var(--icl-duration-base) var(--icl-ease);
}
a.icl-card--feature { display: block; color: inherit; text-decoration: none; }
a.icl-card--feature:hover {
  box-shadow: var(--icl-shadow-md);
  transform: translateY(-2px);
  text-decoration: none;
}

.icl-card__kicker {
  font-family: var(--icl-font-sans);
  font-weight: 700;
  font-size: var(--icl-text-xs);
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-caps);
  color: var(--icl-color-eyebrow);
  margin-bottom: var(--icl-space-2);
}
.icl-card__title { font-size: var(--icl-text-xl); margin-bottom: var(--icl-space-2); }
.icl-card__body { color: var(--icl-color-text-muted); margin-bottom: 0; }
.icl-card__meta {
  margin-top: var(--icl-space-4);
  font-size: var(--icl-text-sm);
  color: var(--icl-color-text-subtle);
}

/* Person card */
.icl-person { text-align: center; }
.icl-person__photo {
  width: 7.5rem; height: 7.5rem;
  margin: 0 auto var(--icl-space-3);
  border-radius: var(--icl-radius-full);
  object-fit: cover;
  background: var(--icl-color-surface-sunken);
}
.icl-person__initials {
  display: flex; align-items: center; justify-content: center;
  font-family: var(--icl-font-display);
  font-size: var(--icl-text-2xl);
  font-weight: 700;
  color: var(--icl-color-accent-strong);
  background: var(--icl-color-accent-soft);
}
/* Duotone photo treatment — a CSS gradient map of [accent ink → white].
   The grayscale photo screens onto the frame's ink-colored backdrop:
   shadows take the ink color, highlights go to warm white. The backdrop
   is the tonal floor, so the ink mixes accent toward heading-dark to
   keep faces legible; contrast spreads the midtones before the blend.
   isolation keeps the blend from reaching the band/card behind the
   circle. Knobs are per-element tunable (same pattern as the fx knobs). */
.icl-person__photo-frame {
  --icl-duotone-ink-mix: 30%;   /* how far the ink darkens from accent */
  --icl-duotone-contrast: 1.5;  /* midtone spread, pre-blend           */
  --icl-duotone-paper: 0.93;    /* <1 warms highlights off pure white  */
  width: 7.5rem; height: 7.5rem;
  margin: 0 auto var(--icl-space-3);
  position: relative;
  border-radius: var(--icl-radius-full);
  overflow: hidden;
  isolation: isolate;
  /* NO background here: browsers paint the element's own background out to
     the full rounded edge but clip children slightly tighter, so a painted
     backdrop always peeks through as a hairline ring the photo can never
     cover. The ink backdrop lives on ::before instead — a child, clipped
     like the photo and inset 1px inside its coverage. */
}
/* No inset and no radius of its own: the frame's clip must be the ONLY
   rounded edge in the stack. Any inset leaves an untinted photo annulus;
   any own-radius adds a second anti-aliased edge for the blend to reveal. */
.icl-person__photo-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in srgb,
    var(--icl-color-accent),
    var(--icl-color-heading) var(--icl-duotone-ink-mix));
  transition: background-color var(--icl-duration-base) var(--icl-ease);
}
.icl-person__photo-frame > .icl-person__photo {
  width: 100%; height: 100%;
  margin: 0;
  border-radius: 0; /* the frame clips; a second rounded edge ghosts a ring */
  filter: grayscale(1)
          contrast(var(--icl-duotone-contrast))
          brightness(var(--icl-duotone-paper));
  mix-blend-mode: screen;
  transition: filter var(--icl-duration-base) var(--icl-ease);
}
/* #000 is screen's blend identity (screen over black = photo unchanged),
   not a rendered color — the photo fully covers it. Not a visible use of
   pure black. */
.icl-person:hover .icl-person__photo-frame::before,
.icl-person__photo-frame:hover::before {
  background: #000;
}
.icl-person:hover .icl-person__photo-frame > .icl-person__photo,
.icl-person__photo-frame:hover > .icl-person__photo {
  filter: none;
}
.icl-person__name { font-weight: 700; color: var(--icl-color-heading); margin: 0; }
.icl-person__role { font-size: var(--icl-text-sm); color: var(--icl-color-text-muted); margin: 0; }

/* Stat */
.icl-stat { border-left: var(--icl-keyline-width) solid var(--icl-color-keyline); padding-left: var(--icl-space-4); }
.icl-stat__value {
  font-family: var(--icl-font-display);
  font-weight: 700;
  font-size: var(--icl-text-5xl);
  line-height: 1;
  color: var(--icl-color-heading);
}
.icl-stat__label {
  font-size: var(--icl-text-sm);
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-wide);
  color: var(--icl-color-text-muted);
}
.icl-section--inverse .icl-stat__value { color: var(--icl-color-inverse-heading); }

/* --------------------------------------------------------------------------
   7b · Media frames & collage feature
   -------------------------------------------------------------------------- */
/* Frame — an image "window" that holds its own shape no matter the source
   image's dimensions (the modern form of the transparent-gif spacer trick:
   the frame owns the aspect ratio; the real image rides behind as a cover
   background and is cropped to fit).
     <div class="icl-frame" role="img" aria-label="…"
          style="--icl-frame-image: url('/files/photo.jpg'); --icl-frame-ratio: 3 / 4"></div>
   Purely decorative frames use aria-hidden="true" instead of role/label. */
.icl-frame {
  display: block;
  width: 100%;
  aspect-ratio: var(--icl-frame-ratio, 4 / 3);
  background-image: var(--icl-frame-image, none);
  background-size: cover;
  background-position: var(--icl-frame-position, center);
  background-color: var(--icl-color-surface-sunken); /* shows until the image paints */
  border-radius: var(--icl-radius-sm);
  /* Photos read as physical objects — they carry the large shadow by
     default. Tune per band with --icl-frame-shadow. */
  box-shadow: var(--icl-frame-shadow, var(--icl-shadow-lg));
}

/* Collage feature — the tennessee.edu "How UT Impacts Your Life" pattern in
   ICL clothes: a staggered three-frame collage beside a headline + body
   column. Unlike the UT original (one pre-baked PNG), each frame is a real
   .icl-frame, so any image fits any slot. Put the pattern inside a band;
   the signature .icl-background-fx is the ICL answer to UT's faint
   triangle-pattern backdrop. */
.icl-collage {
  display: grid;
  gap: var(--icl-space-7);
  align-items: center;
  /* Collage photos wear a tight offset shadow hugging the print (David's
     tuned value, 2026-08-05) instead of the frame default's soft ambient
     lg — inherits down to the .icl-frame children via --icl-frame-shadow. */
  --icl-frame-shadow: 2px 2px 5px rgba(85, 85, 85, 0.65);
}
.icl-collage__media {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--icl-space-4);
  align-items: start;
  align-self: start;
}
/* Slot geometry (from the reference composition): big landscape top-left,
   portrait beside it vertically centered against the stack, small landscape
   below the big one with their right edges aligned.
   Each slot presets a ratio; override per-frame with --icl-frame-ratio. */
.icl-collage__media .icl-frame:nth-child(1) {
  grid-column: 1 / 9;
  grid-row: 1;
  --icl-frame-ratio: 4 / 3;
}
.icl-collage__media .icl-frame:nth-child(2) {
  grid-column: 9 / 13;
  grid-row: 1 / span 2;
  align-self: center;
  --icl-frame-ratio: 3 / 4;
}
.icl-collage__media .icl-frame:nth-child(3) {
  grid-column: 3 / 9;
  grid-row: 2;
  --icl-frame-ratio: 16 / 10;
}
.icl-collage__body { max-width: 34em; }
.icl-collage__body > :last-child { margin-bottom: 0; }
@media (min-width: 56rem) {
  /* Media/text split. Tunable per band via --icl-collage-split — shrinking
     the media share shrinks the photos in both dimensions (frame heights
     follow their widths), e.g. minmax(0, 6.3fr) minmax(0, 5.7fr) for ~10%
     smaller photos. */
  .icl-collage { grid-template-columns: var(--icl-collage-split, minmax(0, 7fr) minmax(0, 5fr)); }
}

/* --------------------------------------------------------------------------
   8 · Navbar
   -------------------------------------------------------------------------- */
.icl-navbar {
  background: var(--icl-color-inverse-bg);
  border-bottom: var(--icl-keyline-width) solid var(--icl-color-keyline);
  position: sticky;
  top: 0;
  z-index: 50;
}
.icl-navbar__inner {
  display: flex;
  align-items: center;
  gap: var(--icl-space-5);
  min-height: 3.5rem;
}
.icl-navbar__brand {
  display: flex;
  align-items: baseline;
  gap: var(--icl-space-2);
  font-family: var(--icl-font-display);
  font-weight: 700;
  font-size: var(--icl-text-xl);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--icl-color-inverse-heading);
  text-decoration: none;
}
.icl-navbar__brand:hover { color: var(--icl-color-inverse-heading); text-decoration: none; }
.icl-navbar__brand-mark { color: var(--icl-color-accent-inverse); }
/* The mark is the ICL lettermark SVG inlined with fill: currentColor, so it
   takes the same theme accent as the text mark it replaced (a text fallback
   still works). Baseline flex alignment rests the mark on the text baseline. */
.icl-navbar__brand-mark svg {
  display: block;
  height: 0.95em;
  width: auto;
  fill: currentColor;
}
.icl-navbar__brand-project {
  color: var(--icl-color-inverse-text);
  font-weight: 700;
  font-size: 1.1em;
  border-left: 1px solid var(--icl-color-inverse-border);
  padding-left: var(--icl-space-2);
}

.icl-navbar__nav {
  display: flex;
  align-items: stretch;
  align-self: flex-end;   /* bottom-align so the active link's underline lands
                             exactly on the navbar keyline (not 1–2px above it) */
  gap: var(--icl-space-1);
  margin-left: auto;
  list-style: none;
  padding: 0; margin-block: 0;
}
.icl-navbar__link {
  display: flex;
  align-items: center;
  padding: 0 var(--icl-space-3);
  min-height: 3.5rem;
  font-size: var(--icl-text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-wide);
  color: var(--icl-color-inverse-text);
  text-decoration: none;
  border-bottom: var(--icl-keyline-width) solid transparent;
  margin-bottom: calc(-1 * var(--icl-keyline-width));
  transition: color var(--icl-duration-fast) var(--icl-ease);
}
.icl-navbar__link:hover { color: var(--icl-color-inverse-heading); text-decoration: none; }
.icl-navbar__link[aria-current="page"], .icl-navbar__link--active {
  color: var(--icl-color-inverse-heading);
  border-bottom-color: var(--icl-color-inverse-heading);
}

.icl-navbar__toggle {
  display: none;
  margin-left: auto;
  background: none;
  border: 1px solid var(--icl-color-inverse-border);
  border-radius: var(--icl-radius-sm);
  color: var(--icl-color-inverse-heading);
  font: inherit;
  padding: var(--icl-space-1) var(--icl-space-3);
  cursor: pointer;
}

@media (max-width: 56rem) {
  .icl-navbar__toggle { display: block; }
  .icl-navbar__nav {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    gap: 0;
    background: var(--icl-color-inverse-bg);
    border-bottom: var(--icl-keyline-width) solid var(--icl-color-keyline);
    padding: var(--icl-space-2) var(--icl-container-pad);
  }
  .icl-navbar__nav.is-open { display: flex; }
  .icl-navbar__link { min-height: 2.75rem; border-bottom: 0; margin-bottom: 0; }
  .icl-navbar__link[aria-current="page"] { color: var(--icl-color-accent-inverse); }
}

/* --------------------------------------------------------------------------
   9 · Hero / banner
   -------------------------------------------------------------------------- */
.icl-hero {
  background: var(--icl-color-inverse-bg);
  color: var(--icl-color-inverse-text);
  padding-block: var(--icl-space-9);
  position: relative;
}
.icl-hero .icl-display { color: var(--icl-color-inverse-heading); }
.icl-hero .icl-eyebrow { color: var(--icl-color-eyebrow-inverse); }
.icl-hero__lede {
  font-size: var(--icl-text-xl);
  line-height: var(--icl-leading-snug);
  max-width: 38em;
  /* No color of its own: the band supplies it (inverse-text on stone,
     ink on light hero bands, on-accent on accent bands). */
}
.icl-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--icl-space-3);
  margin-top: var(--icl-space-6);
}
/* Media lockup — a content image (publication cover, screenshot) takes the
   body slot; body copy, when present, sits to the image's right and wraps
   under it only when the row runs out of room. */
.icl-hero__media {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--icl-space-5);
}
.icl-hero__media .icl-hero__lede { flex: 1 1 16em; }
.icl-hero__thumb {
  display: block;
  flex: none;
  width: min(10rem, 40%);
  border-radius: var(--icl-radius-sm);
  box-shadow: var(--icl-shadow-lg);
}
.icl-hero--compact { padding-block: var(--icl-space-7); }

/* --------------------------------------------------------------------------
   10 · Tabs (project-site section nav)
   -------------------------------------------------------------------------- */
.icl-tabs {
  display: flex;
  gap: var(--icl-space-1);
  border-bottom: 1px solid var(--icl-color-border);
  list-style: none;
  padding: 0;
  margin: 0 0 var(--icl-space-5);
  overflow-x: auto;
}
.icl-tabs__tab {
  padding: var(--icl-space-3) var(--icl-space-4);
  font-weight: 600;
  font-size: var(--icl-text-sm);
  color: var(--icl-color-text-muted);
  text-decoration: none;
  border: 0;
  background: none;
  cursor: pointer;
  border-bottom: var(--icl-keyline-width) solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  font-family: var(--icl-font-sans);
}
.icl-tabs__tab:hover { color: var(--icl-color-heading); text-decoration: none; }
.icl-tabs__tab[aria-selected="true"], .icl-tabs__tab--active {
  color: var(--icl-color-accent-strong);
  border-bottom-color: var(--icl-color-accent);
}

/* --------------------------------------------------------------------------
   11 · Tables
   -------------------------------------------------------------------------- */
.icl-table-wrap { overflow-x: auto; }

.icl-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--icl-text-sm);
}
.icl-table caption {
  text-align: left;
  font-weight: 700;
  color: var(--icl-color-heading);
  padding-bottom: var(--icl-space-3);
}
.icl-table th {
  font-family: var(--icl-font-display);
  font-weight: 600;
  font-size: var(--icl-text-sm);
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-wide);
  text-align: left;
  color: var(--icl-color-heading);
  border-bottom: 2px solid var(--icl-color-heading);
  padding: var(--icl-space-2) var(--icl-space-3);
}
.icl-table td {
  padding: var(--icl-space-3);
  border-bottom: 1px solid var(--icl-color-border);
  vertical-align: top;
}
.icl-table--striped tbody tr:nth-child(even) { background: var(--icl-color-surface-sunken); }
.icl-table tbody tr:hover { background: var(--icl-color-accent-soft); }

/* --------------------------------------------------------------------------
   12 · Publication list
   -------------------------------------------------------------------------- */
.icl-pubs {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--icl-space-3);
}
/* Each publication is a raised white card with a left accent keyline —
   reads well lifted off the sunken limestone band. */
.icl-pub {
  background: var(--icl-color-surface-raised);
  border: 1px solid var(--icl-color-border);
  border-left: var(--icl-keyline-width) solid var(--icl-color-keyline);
  border-radius: 0; /* keyline surfaces are square */
  box-shadow: var(--icl-shadow-sm);
  padding: var(--icl-space-4) var(--icl-space-5);
}
.icl-pub__title {
  font-size: var(--icl-text-lg);
  font-weight: 700;
  color: var(--icl-color-heading);
  margin: 0 0 var(--icl-space-1);
}
.icl-pub__title a { color: inherit; }
.icl-pub__title a:hover { color: var(--icl-color-accent-strong); }
/* Authors read as Proxima caps — the surname half of the signature style,
   applied to the whole name (a serif bold initial mismatches its surname,
   so pubs deliberately do NOT use the full signature treatment). */
.icl-pub__authors {
  font-size: var(--icl-text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.045em;
  color: var(--icl-color-text-muted);
  margin: 0 0 var(--icl-space-1);
}
/* Not italic as a block: citation italics belong only to journal/book
   titles — mark those with <i> in the venue text; locations and dates
   stay roman, separated by commas (never em dashes). */
.icl-pub__venue {
  font-family: var(--icl-font-sans);
  font-size: var(--icl-text-sm);
  color: var(--icl-color-text-muted);
  margin: 0 0 var(--icl-space-2);
}
.icl-pub__links {
  display: flex;
  align-items: center;
  gap: var(--icl-space-2);
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   13 · Alerts / callouts
   -------------------------------------------------------------------------- */
.icl-alert {
  display: flex;
  gap: var(--icl-space-3);
  padding: var(--icl-space-4);
  border-radius: 0; /* keyline surfaces are square */
  border: 1px solid var(--icl-color-border);
  border-left: var(--icl-keyline-width) solid var(--icl-color-info);
  background: var(--icl-color-info-bg);
  color: var(--icl-color-text);
  margin-bottom: var(--icl-space-4);
}
.icl-alert__title { font-weight: 700; color: var(--icl-color-heading); margin: 0 0 var(--icl-space-1); }
.icl-alert p:last-child { margin-bottom: 0; }

.icl-alert--success { border-left-color: var(--icl-color-success); background: var(--icl-color-success-bg); }
.icl-alert--warning { border-left-color: var(--icl-color-warning); background: var(--icl-color-warning-bg); }
.icl-alert--danger  { border-left-color: var(--icl-color-danger);  background: var(--icl-color-danger-bg); }
.icl-alert--accent  { border-left-color: var(--icl-color-accent);  background: var(--icl-color-accent-soft); }

/* --------------------------------------------------------------------------
   14 · Code block
   -------------------------------------------------------------------------- */
.icl-codeblock {
  background: var(--icl-color-inverse-bg);
  color: var(--icl-color-inverse-text);
  border-radius: 0; /* keyline surfaces are square */
  border-top: var(--icl-keyline-width) solid var(--icl-color-keyline);
  padding: var(--icl-space-4) var(--icl-space-5);
  overflow-x: auto;
  font-family: var(--icl-font-mono);
  font-size: var(--icl-text-sm);
  line-height: 1.7;
  margin: 0 0 var(--icl-space-4);
}
.icl-codeblock code { background: none; border: 0; padding: 0; font-size: inherit; }

/* --------------------------------------------------------------------------
   15 · Footer
   -------------------------------------------------------------------------- */
.icl-footer {
  background: var(--icl-color-inverse-bg);
  color: var(--icl-color-inverse-text);
  border-top: var(--icl-keyline-width) solid var(--icl-color-keyline);
  padding-block: var(--icl-space-7) var(--icl-space-6);
  font-size: var(--icl-text-sm);
}
.icl-footer a:not([class*="icl-btn"]) { color: var(--icl-color-inverse-text); }
.icl-footer a:not([class*="icl-btn"]):hover { color: var(--icl-color-inverse-link); }
.icl-footer__brand {
  font-family: var(--icl-font-display);
  font-weight: 700;
  font-size: var(--icl-text-xl);
  text-transform: uppercase;
  color: var(--icl-color-inverse-heading);
  margin-bottom: var(--icl-space-2);
}
.icl-footer__heading {
  font-family: var(--icl-font-display);
  font-weight: 600;
  font-size: var(--icl-text-md);
  text-transform: uppercase;
  letter-spacing: var(--icl-tracking-wide);
  color: var(--icl-color-inverse-heading);
  margin: 0 0 var(--icl-space-3);
}
.icl-footer__links { list-style: none; padding: 0; margin: 0; }
.icl-footer__links li { margin-bottom: var(--icl-space-2); }
.icl-footer__legal {
  margin-top: var(--icl-space-6);
  padding-top: var(--icl-space-4);
  border-top: 1px solid var(--icl-color-inverse-border);
  color: var(--icl-color-inverse-text-subtle);
  display: flex;
  flex-wrap: wrap;
  gap: var(--icl-space-4);
  justify-content: space-between;
}

/* --------------------------------------------------------------------------
   16 · Breadcrumbs
   -------------------------------------------------------------------------- */
.icl-breadcrumbs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--icl-space-2);
  list-style: none;
  padding: 0;
  margin: 0 0 var(--icl-space-4);
  font-size: var(--icl-text-sm);
  color: var(--icl-color-text-subtle);
}
.icl-breadcrumbs li:not(:last-child)::after { content: "/"; margin-left: var(--icl-space-2); color: var(--icl-color-border-strong); }
.icl-breadcrumbs [aria-current] { color: var(--icl-color-text); font-weight: 600; }

/* --------------------------------------------------------------------------
   17 · Utilities
   -------------------------------------------------------------------------- */
.icl-u-text-muted { color: var(--icl-color-text-muted); }
.icl-u-text-center { text-align: center; }
.icl-u-mono { font-family: var(--icl-font-mono); }
.icl-u-serif { font-family: var(--icl-font-serif); }
.icl-u-mt-0 { margin-top: 0; }
.icl-u-mb-0 { margin-bottom: 0; }
.icl-u-flow > * + * { margin-top: var(--icl-space-4); }
.icl-u-cluster { display: flex; flex-wrap: wrap; gap: var(--icl-space-2); align-items: center; }
.icl-u-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}
