/*
 * SSP2 supplement sheet.
 *
 * public/css/main.css is a compiled artifact with no compiler installed and is
 * FROZEN under R2 (2026-08-01). New CSS lands here, in a sibling sheet served by
 * staticRoutes(), linked after main.css so the cascade favours it.
 *
 * .void-slot — the composed void-ground image slot.
 *
 * Brief section 4 (S3 STUDIO ORIGIN, S5 TRANSLATION PLUS BESPOKE): "Image slot
 * renders as composed void-ground." Brief section 3.6: "Edge states are designed,
 * not defaulted: data-bound sections arrive composed, no spinners, no shimmer on
 * narrative surfaces."
 *
 * It is therefore a finished surface, not a loading affordance and not an image
 * container: no radius, no shadow, no gradient, no animation, no shimmer, no
 * object-fit. A slot with no asset is complete as it stands.
 *
 * The ground value is the literal compiled into main.css at .bg-ground
 * (background-color:rgb(14 13 11/var(--tw-bg-opacity,1))), read out of the sheet
 * rather than re-derived from a token or invented as a hex.
 *
 * It fills its box rather than declaring one. The box comes from the aspect
 * utilities already compiled in main.css (aspect-16/9, aspect-4/3, aspect-square)
 * or from the parent's own height, so this sheet invents no ratio.
 */

.void-slot {
  display: block;
  width: 100%;
  height: 100%;
  background-color: rgb(14 13 11);
}

/*
 * .header-scrim, the dark top band behind the TRANSPARENT header only.
 *
 * The homepage hero is light at the top of the viewport, so cream nav on bare
 * hero is not reliably legible. This lays a top-down darkening behind the nav
 * that has fully faded out by the bottom of the header band, leaving the hero
 * itself untouched below it.
 *
 * Authored here rather than composed from utilities because main.css compiles
 * bg-gradient-to-t ONLY: there is no to-b direction and no opacity step other
 * than from-ground/80 and via-ground/30 (grepped 2026-08-13). main.css is
 * FROZEN under R2, so the missing direction cannot be compiled into it.
 *
 * The colour is the .bg-ground literal rgb(14 13 11) read out of main.css, the
 * same source .void-slot reads. No token is re-derived and no hex is invented.
 *
 * Height is 8rem: the header band is .h-20 (height:5rem, read from main.css)
 * plus 3rem of fade past it, so the gradient is finished before it reaches
 * page content.
 *
 * STACKING IS SELF-CONTAINED AND NON-NEGATIVE, ruled 2026-08-13.
 *
 * The previous revision used z-index -1, which renders only while the header
 * keeps its own stacking context: the correctness of this rule depended on a
 * z-40 sitting in a different file, and nothing in either file said so. That
 * coupling is gone. The scrim now sits at z-index 0 and every header layer
 * that must paint over it carries .header-layer at z-index 1, so the order is
 * decided by two values in this sheet and holds whatever the header's own
 * z-index becomes.
 *
 * The scrim is the header's FIRST child, so at equal stacking level DOM order
 * would already put the nav on top; .header-layer states it rather than
 * leaning on source order. pointer-events: none so it cannot take a click that
 * belongs to the nav.
 *
 * It is attached to the transparent variant ONLY. The opaque header keeps its
 * bg-surface/80 + backdrop-blur-xl + border-b and renders no scrim.
 */

.header-scrim {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 8rem;
  background: linear-gradient(
    to bottom,
    rgba(14, 13, 11, 0.92) 0%,
    rgba(14, 13, 11, 0.55) 45%,
    rgba(14, 13, 11, 0) 100%
  );
  pointer-events: none;
  z-index: 0;
}

/*
 * .header-layer — a header child that must paint ON the scrim, not under it.
 *
 * Carried by BOTH header layers, and both are load-bearing:
 *   the nav bar row      the logo, the links, the dropdown triggers, the CTA
 *   #mobile-nav          the open mobile panel
 *
 * The mobile panel is the half that is easy to miss. It is an in-flow sibling
 * of the nav row, so without this it paints below a positioned scrim, and the
 * scrim's lower 3rem would wash the top of the panel the moment it opened on
 * the homepage. One class on both keeps a single value deciding the order.
 *
 * Inert on the opaque header, which renders no scrim: position:relative with
 * z-index:1 over nothing changes no pixel on the other eight routes.
 */

.header-layer {
  position: relative;
  z-index: 1;
}

/*
 * .technique-card — the <article> inside the /technology/ card Link.
 *
 * At rest it adds NOTHING. The card renders today exactly as it did before this
 * rule existed; every resting value still comes from the compiled utilities on
 * the element (border-line, bg-surface). A hover affordance must not change the
 * page nobody is pointing at.
 *
 * Hover is a BORDER CHANGE ONLY. One literal, read out of main.css, never
 * invented:
 *   border -> rgb(138 118 96)   the .border-bronze / .text-bronze literal
 *
 * The background does not move. An earlier revision lifted the surface with a
 * composed mix, because main.css compiles exactly three background neutrals
 * (ground, surface, bronze) and no lighter fourth step to lift to. Ruled out
 * 2026-08-08: the affordance is carried by the border alone, and the card keeps
 * its resting surface at every pointer state.
 *
 * 240ms on cubic-bezier(0.25, 0.1, 0.0, 1.0) is the house curve already carried
 * by public/js/motion.js. Transition names border-color only, because nothing
 * else animates: no background, no transform, no shadow, no scale.
 *
 * The whole thing sits inside @media (hover: hover) so a touch device, which has
 * no true hover, never latches a sticky hovered card after a tap.
 */

@media (hover: hover) {
  .technique-card {
    transition: border-color 240ms cubic-bezier(0.25, 0.1, 0.0, 1.0);
  }

  a:hover .technique-card {
    border-color: rgb(138 118 96);
  }
}

/*
 * .technique-forward — the forward link at the foot of a technique subpage.
 *
 * Rest colour is the .text-bronze utility on the element. Hover moves it to the
 * .text-mist literal rgb(232 228 220), both read out of main.css.
 */

@media (hover: hover) {
  .technique-forward {
    transition: color 240ms cubic-bezier(0.25, 0.1, 0.0, 1.0);
  }

  .technique-forward:hover {
    color: rgb(232 228 220);
  }
}

/*
 * Reduced motion drops the TRANSITION, never the state. A user who asks for less
 * motion still gets the full hover affordance, it simply arrives instantly.
 */

@media (hover: hover) and (prefers-reduced-motion: reduce) {
  .technique-card,
  .technique-forward {
    transition: none;
  }
}

/*
 * .font-medium — weight 500.
 *
 * main.css compiles exactly two font utilities, .font-sans and .font-mono, and
 * NO weight utility at all (grepped 2026-08-13: every `.font-*` selector in the
 * sheet is one of those two). The sheet is FROZEN under R2, so the token cannot
 * be compiled into it and lands here instead.
 *
 * 500 is the top of the range the face actually carries: app/globals.css:45
 * declares `font-weight: 300 500` on the Jost variable @font-face, so 500 is a
 * real instance rather than a synthesised bold. It is also the ceiling set by
 * repo design law, "no bold above weight 500".
 */

.font-medium {
  font-weight: 500;
}
