/* ==========================================================================
   JASKEERAT SINGH — PERSONAL CYBERSECURITY PORTFOLIO
   Hand-written CSS. No build step, no dependencies, no frameworks.

   Visual direction follows the editorial / technical-documentation character
   of the SUSS reference: black paper, white ink, a monospaced display voice,
   hard 2px rules, uppercase micro-labels, numbered sections and inverted
   bands used as rhythm. Prose passages switch to a sans-serif reading voice
   so long documents stay comfortable to read.

   CONTENTS
   01  Design tokens
   02  Reset and base elements
   03  Typography
   04  Layout primitives
   05  Skip link, header and navigation
   06  Hero
   07  Bands (numbered sections)
   08  Editorial rows and archive lists
   09  Grids, tags, notes and tables
   10  Document pages (writeups and breach reports)
   11  Resume
   12  Project page
   13  Footer
   14  Utilities
   15  Print
   ========================================================================== */


/* ==========================================================================
   01  DESIGN TOKENS
   ========================================================================== */

@layer reset, base, layout, components, utilities, print;

@layer base {
  :root {
    color-scheme: dark;

    /* Colour ----------------------------------------------------------- */
    /* A warm near-black rather than #000, and a warm off-white rather than
       #fff: the page reads as printed stock instead of a screen, and the
       pure-white contrast is less harsh over a long read. */
    --paper: #0c0b09;
    --ink: #f4f2ec;
    --dim: #8f897d;          /* 5.7:1 against --paper */

    /* The two light "paper" modes: the inverted band and the breach-report
       archive. They sit a step apart so the archive keeps its own identity.
       --paper-light is separate from --ink on purpose: the inverted band
       overrides --ink, and a rule that read `background: var(--ink)` would
       then resolve to the overridden value and the band would stay dark. */
    --paper-light: #f4f2ec;
    --paper-warm: #ece7dc;
    --ink-warm: #12110e;
    --dim-warm: #55504a;     /* 6.5:1 against --paper-warm */

    /* A single ember accent. Used sparingly, and always with the type
       scale doing the heavy lifting, so colour adds a second channel of
       hierarchy rather than replacing the first. */
    --accent: #e05a3c;       /* 5.3:1 against --paper */
    --accent-ink: #9e3a20;   /* 5.9:1 against --paper-warm */

    /* Rules ------------------------------------------------------------ */
    --rule: 2px;
    --rule-hair: 1px;

    /* Metrics ---------------------------------------------------------- */
    --maxw: 1160px;
    --measure: 68ch;
    --pad: clamp(1.125rem, 4vw, 3rem);
    --stack: clamp(2.25rem, 5vw, 4.5rem);

    /* Type ------------------------------------------------------------- */
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
    --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

    --step--2: clamp(0.68rem, 0.66rem + 0.08vw, 0.72rem);
    --step--1: clamp(0.78rem, 0.75rem + 0.12vw, 0.86rem);
    --step-0:  clamp(0.95rem, 0.92rem + 0.16vw, 1.06rem);
    --step-1:  clamp(1.1rem, 1.02rem + 0.4vw, 1.35rem);
    --step-2:  clamp(1.35rem, 1.12rem + 1.05vw, 1.9rem);
    --step-3:  clamp(1.7rem, 1.28rem + 2vw, 2.6rem);
    --step-4:  clamp(2.5rem, 1.55rem + 4.6vw, 4.4rem);
    --step-5:  clamp(2.9rem, 1rem + 9.2vw, 6.4rem);

    --track-wide: 0.18em;
    --track-mid: 0.12em;
    --track-tight: 0.04em;
  }
}


/* ==========================================================================
   02  RESET AND BASE ELEMENTS
   ========================================================================== */

@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  body,
  h1, h2, h3, h4, h5, h6,
  p, figure, blockquote, dl, dd,
  ul, ol, pre {
    margin: 0;
  }

  ul, ol {
    padding: 0;
  }

  img, svg, video, iframe {
    max-width: 100%;
  }

  img, video {
    height: auto;
  }
}

@layer base {
  html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: 6rem;
  }

  /* The bar is sticky and gains a row when the navigation wraps, so the
     anchor offset has to grow with it — otherwise a jump lands the heading
     behind the bar. These offsets match the bar heights in section 05. */
  @media (max-width: 41rem) {
    html {
      scroll-padding-top: 7rem;
    }
  }

  @media (max-width: 26rem) {
    html {
      scroll-padding-top: 8rem;
    }
  }

  body {
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: var(--step-0);
    line-height: 1.55;
    letter-spacing: var(--track-tight);
    overflow-wrap: break-word;
  }

  a {
    color: inherit;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
  }

  a:hover {
    text-decoration-thickness: 2px;
  }

  :focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
  }

  /* Safari drops list semantics when a list is unstyled or flexed; role="list"
     on the <ul> restores them without changing the visual treatment. */

  @media (prefers-reduced-motion: reduce) {
    html {
      scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
    }
  }
}


/* ==========================================================================
   03  TYPOGRAPHY
   ========================================================================== */

@layer base {
  h1, h2, h3, h4, h5, h6 {
    margin: 0;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.04;
    text-wrap: balance;
  }

  p {
    text-wrap: pretty;
  }

  strong, b {
    font-weight: 700;
  }

  /* Small uppercase metadata voice used across every page. */
  .label,
  .sec,
  .eyebrow {
    font-size: var(--step--2);
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    font-weight: 700;
  }

  .dim {
    color: var(--dim);
  }
}


/* ==========================================================================
   04  LAYOUT PRIMITIVES
   ========================================================================== */

@layer layout {
  .wrap {
    max-width: var(--maxw);
    margin-inline: auto;
    padding-inline: var(--pad);
  }

  .band {
    padding-block: var(--stack);
    border-bottom: var(--rule) solid currentColor;
  }

  .band--invert {
    background: var(--paper-light);
    color: var(--ink-warm);
    --ink: var(--ink-warm);
    --paper: var(--paper-light);
    --dim: var(--dim-warm);
    --accent: var(--accent-ink);
  }

  .band--warm {
    background: var(--paper-warm);
    color: var(--ink-warm);
    --ink: var(--ink-warm);
    --paper: var(--paper-warm);
    --dim: var(--dim-warm);
    --accent: var(--accent-ink);
  }

  .band--tight {
    padding-block: clamp(1.5rem, 3vw, 2.5rem);
  }
}


/* ==========================================================================
   05  SKIP LINK, HEADER AND NAVIGATION
   ========================================================================== */

@layer components {
  .skip {
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 0;
    z-index: 100;
    padding: 0.75rem 1.25rem;
    background: var(--ink);
    color: var(--paper);
    font-size: var(--step--1);
    letter-spacing: var(--track-mid);
    text-transform: uppercase;
    text-decoration: none;
    transform: translateY(-120%);
  }

  .skip:focus {
    transform: translateY(0);
  }

  .bar {
    position: sticky;
    inset-block-start: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
    padding-block: 0.875rem;
    /* Keep the bar's contents on the page column rather than on the viewport
       edge. Once the viewport is wider than --maxw the wrap is centred, and a
       bar pinned to the viewport would run ~90px out of line with it. */
    padding-inline: calc(max(0px, (100% - var(--maxw)) / 2) + var(--pad));
    background: var(--paper);
    color: var(--ink);
    border-bottom: var(--rule) solid currentColor;
  }

  .bar__mark {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    font-weight: 800;
    font-size: 1.05rem;
    letter-spacing: 0.12em;
    text-decoration: none;
    white-space: nowrap;
  }

  .bar__mark:hover {
    text-decoration: none;
  }

  .bar__glyph {
    inline-size: 0.95rem;
    block-size: 0.95rem;
    fill: currentColor;
    flex: none;
  }

  .bar__by {
    font-size: var(--step--2);
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    color: var(--accent);
  }

  .bar__nav {
    margin-inline-start: auto;
    min-inline-size: 0;
  }

  .bar__nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    text-align: end;
  }

  .bar__nav li {
    display: inline-block;
    margin-inline-end: 0.75rem;
  }

  .bar__nav li:last-child {
    margin-inline-end: 0;
  }

  .bar__nav a {
    display: inline-block;
    padding-block: 0.25rem;
    font-size: 0.78rem;
    letter-spacing: var(--track-mid);
    text-transform: uppercase;
    text-decoration: none;
    border-block-end: var(--rule) solid transparent;
  }

  .bar__nav a:hover {
    text-decoration: none;
    background: var(--accent);
    color: var(--paper);
  }

  .bar__nav a[aria-current="page"] {
    background: var(--accent);
    color: var(--paper);
  }

  /* The byline is the first thing to go: it is decoration, and the navigation
     needs the room more. */
  @media (max-width: 54rem) {
    .bar__by {
      display: none;
    }
  }

  /* Set the navigation a step smaller before it is forced onto its own row, so
     it keeps the wordmark's company for another ~130px of viewport. */
  @media (max-width: 43rem) {
    .bar__nav li {
      margin-inline-end: 0.5rem;
    }

    .bar__nav a {
      padding-block: 0.35rem;
      font-size: 0.72rem;
      letter-spacing: 0.05em;
    }
  }

  /* Below this the navigation cannot share the row even at the smaller size,
     so it drops beneath the wordmark: full width, left-aligned. */
  @media (max-width: 41rem) {
    .bar {
      gap: 0.5rem 0.75rem;
      padding-block: 0.7rem;
    }

    .bar__nav {
      margin-inline-start: 0;
      inline-size: 100%;
      text-align: start;
    }

    .bar__nav ul {
      text-align: start;
    }
  }

  /* The narrowest phones: tighten once more rather than let a link break its
     own word or spill onto a third row. */
  @media (max-width: 26rem) {
    .bar__nav li {
      margin-inline-end: 0.375rem;
    }

    .bar__nav a {
      font-size: 0.68rem;
      letter-spacing: 0.02em;
    }
  }
}


/* ==========================================================================
   06  HERO
   ========================================================================== */

@layer components {
  .hero {
    padding-block: clamp(1.75rem, 5vw, 4.5rem) clamp(1.75rem, 4.5vw, 3.5rem);
    border-bottom: var(--rule) solid currentColor;
  }

  .hero__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    align-items: start;
    gap: clamp(1.5rem, 3vw, 3rem);
    margin-block-start: clamp(1.5rem, 3.5vw, 2.75rem);
  }

  .hero__title {
    font-size: var(--step-5);
    line-height: 0.86;
    letter-spacing: -0.04em;
    margin-inline-start: -0.02em;
  }

  .hero__full {
    margin-block-start: 0.875rem;
    font-size: clamp(0.82rem, 1.9vw, 1.05rem);
    text-transform: uppercase;
    letter-spacing: 0.3em;
    color: var(--accent);
    text-wrap: balance;
  }

  .hero__lede {
    max-inline-size: 58ch;
    margin-block-start: 0;
    font-family: var(--font-sans);
    font-size: var(--step-1);
    line-height: 1.6;
  }

  .hero__cta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.875rem;
    margin-block-start: clamp(1.25rem, 3vw, 2rem);
  }

  .hero__fine {
    margin-block-start: 1rem;
    font-size: var(--step--1);
    color: var(--dim);
    max-inline-size: 56ch;
  }

  .hero__fine a {
    color: var(--ink);
  }

  /* Outlined action link. */
  .btn {
    display: inline-block;
    border: var(--rule) solid currentColor;
    padding: 0.8rem 1.5rem;
    text-transform: uppercase;
    font-size: var(--step--1);
    font-weight: 700;
    letter-spacing: var(--track-mid);
    text-decoration: none;
  }

  .btn:hover {
    background: var(--accent);
    color: var(--paper);
  }

  .btn--ghost:hover {
    background: transparent;
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 5px;
  }

  .bullets {
    list-style: disc;
    padding-inline-start: 1.35rem;
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.6;
  }

  .bullets li + li {
    margin-block-start: 0.4rem;
  }

  .hero__main {
    min-inline-size: 0;
  }

  .hero__fig {
    min-inline-size: 0;
  }

  /* The hero figure: a ranked list of the practice areas.
     Three sizes, not one, and the list is grouped by weight — the three
     primary domains set large, the three supporting ones set small and
     indented — so the hierarchy comes from the content itself rather than
     from a single tone repeated. The block is not framed: it has no rule
     above it and none below the last line. */
  .herotri {
    margin: 0;
    text-align: start;
    text-transform: uppercase;
  }

  .herotri span {
    display: block;
    padding-block: 0.4rem;
    border-block-end: var(--rule-hair) solid currentColor;
    line-height: 1.12;
    letter-spacing: -0.015em;
    font-weight: 800;
    font-size: clamp(1.05rem, 1.85vw, 1.6rem);
    color: var(--ink);
  }

  /* The lead area sits a step above the other two primaries. */
  .herotri span:first-child {
    font-size: clamp(1.15rem, 2.1vw, 1.8rem);
    padding-block: 0.5rem 0.4rem;
    border-block-end-color: var(--ink);
  }

  /* A marker on each primary, echoing the mark in the favicon. */
  .herotri span:not(.dim)::before {
    content: "";
    display: inline-block;
    inline-size: 0.4em;
    block-size: 0.4em;
    margin-inline-end: 0.45em;
    background: var(--accent);
    vertical-align: 0.05em;
  }

  /* The supporting areas read as sub-labels. */
  .herotri .dim {
    font-size: clamp(0.78rem, 1.05vw, 0.95rem);
    font-weight: 500;
    letter-spacing: 0.09em;
    color: var(--dim);
    padding-block: 0.5rem;
    padding-inline-start: 1.5rem;
  }

  /* Nothing closes the block. */
  .herotri span:last-child {
    border-block-end: 0;
  }

  @media (max-width: 52rem) {
    .hero__grid {
      grid-template-columns: minmax(0, 1fr);
    }

    .hero__fig {
      margin-block-start: clamp(1.5rem, 5vw, 2.75rem);
    }
  }

  @media (max-width: 40rem) {
    .hero__full {
      letter-spacing: 0.16em;
    }
  }

  /* Stack the actions on a phone. Three ragged pills of different widths read
     as a wrapping accident; one column of equal rows reads as a menu. */
  @media (max-width: 26rem) {
    .hero__cta {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
    }

    .hero__full {
      letter-spacing: 0.12em;
    }
  }
}


/* ==========================================================================
   07  BANDS (NUMBERED SECTIONS)
   ========================================================================== */

@layer components {
  .band__head {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
  }

  .sec {
    display: inline-block;
    border: var(--rule) solid var(--accent);
    color: var(--accent);
    padding: 0.3rem 0.65rem;
    letter-spacing: var(--track-mid);
  }

  .band__head h2 {
    font-size: var(--step-3);
    text-transform: uppercase;
    align-self: stretch;
  }

  .band__lede {
    max-inline-size: 64ch;
    margin-block: clamp(1rem, 2.5vw, 1.75rem) clamp(1.375rem, 3.5vw, 2.5rem);
    font-family: var(--font-sans);
    font-size: var(--step-1);
    line-height: 1.6;
  }

  .band__body {
    max-inline-size: 74ch;
  }

  .band__body--wide {
    max-inline-size: none;
  }

  .band__foot {
    margin-block-start: clamp(1.375rem, 3.5vw, 2.25rem);
  }
}


/* ==========================================================================
   08  EDITORIAL ROWS AND ARCHIVE LISTS
   ========================================================================== */

@layer components {
  .rows {
    container: rows / inline-size;
    border-block-start: var(--rule) solid currentColor;
  }

  .rows__label {
    margin-block: clamp(1.75rem, 4vw, 2.5rem) 0.5rem;
    font-size: var(--step-1);
    text-transform: uppercase;
  }

  .row {
    display: grid;
    grid-template-columns: 3.25rem minmax(0, 1fr) 11rem;
    gap: 0.25rem 1.5rem;
    align-items: start;
    padding-block: clamp(1.125rem, 2.5vw, 1.75rem);
    border-block-end: var(--rule-hair) solid currentColor;
  }

  .row__index {
    font-size: var(--step--2);
    letter-spacing: var(--track-mid);
    color: var(--accent);
    padding-block-start: 0.3rem;
  }

  .row__title {
    font-size: var(--step-2);
    line-height: 1.12;
    margin: 0;
  }

  .row__title a {
    text-decoration: none;
  }

  .row__title a:hover {
    color: var(--accent);
    text-decoration: underline;
    text-underline-offset: 5px;
  }

  .row__desc {
    margin-block-start: 0.5rem;
    max-inline-size: 62ch;
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.6;
    color: var(--dim);
  }

  .row__meta {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    font-size: var(--step--2);
    letter-spacing: var(--track-mid);
    text-transform: uppercase;
    color: var(--dim);
    text-align: end;
  }

  .row__meta > div {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
  }

  .row__meta dt {
    font-weight: 400;
  }

  .row__meta dd {
    margin: 0;
    color: var(--ink);
    font-weight: 700;
  }

  .band--invert .row__desc,
  .band--warm .row__desc {
    color: var(--ink);
    opacity: 0.75;
  }

  .band--invert .row__meta,
  .band--warm .row__meta {
    color: var(--ink);
    opacity: 0.75;
  }

  .band--invert .row__meta dd,
  .band--warm .row__meta dd {
    color: var(--ink);
    opacity: 1;
  }

  .band--invert .row__index,
  .band--warm .row__index {
    color: var(--ink);
    opacity: 0.6;
  }

  @container rows (inline-size < 46rem) {
    .row {
      grid-template-columns: 2.5rem minmax(0, 1fr);
    }

    .row__meta {
      grid-column: 2;
      flex-direction: row;
      flex-wrap: wrap;
      gap: 0.35rem 1.25rem;
      text-align: start;
      margin-block-start: 0.25rem;
    }
  }

  /* Viewport fallback for engines without container query support. */
  @media (max-width: 46rem) {
    .row {
      grid-template-columns: 2.5rem minmax(0, 1fr);
    }

    .row__meta {
      grid-column: 2;
      flex-direction: row;
      flex-wrap: wrap;
      gap: 0.35rem 1.25rem;
      text-align: start;
      margin-block-start: 0.25rem;
    }
  }
}


/* ==========================================================================
   09  GRIDS, TAGS, NOTES AND TABLES
   ========================================================================== */

@layer components {
  /* Hairline cell grid — the reference's structural device. */
  .cells {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    border-block-start: var(--rule) solid currentColor;
    border-inline-start: var(--rule) solid currentColor;
  }

  .cells--wide {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  @media (max-width: 64rem) {
    .cells {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
  }

  @media (max-width: 40rem) {
    .cells,
    .cells--wide {
      grid-template-columns: minmax(0, 1fr);
    }
  }

  .cell {
    border-block-end: var(--rule) solid currentColor;
    border-inline-end: var(--rule) solid currentColor;
    padding: clamp(1.125rem, 3vw, 2rem);
  }

  /* A faint wash keeps the light band from reading as a flat sheet. */
  .band--invert .cells .cell,
  .band--warm .cells .cell {
    background: color-mix(in oklab, var(--accent) 6%, transparent);
  }

  .cell h3 {
    font-size: var(--step-1);
    text-transform: uppercase;
    margin-block-end: 0.625rem;
  }

  .cell p {
    margin: 0;
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.6;
    color: var(--dim);
  }

  .band--invert .cell p,
  .band--warm .cell p {
    color: var(--ink);
    opacity: 0.78;
  }

  .cell__meta {
    display: block;
    margin-block-end: 0.5rem;
    font-size: var(--step--2);
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    color: var(--accent);
  }

  .band--invert .cell__meta,
  .band--warm .cell__meta {
    color: var(--ink);
    opacity: 0.65;
  }

  /* Square outline chips. */
  .tags {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
  }

  .tags li {
    border: var(--rule) solid currentColor;
    padding: 0.45rem 0.75rem;
    font-size: var(--step--2);
    text-transform: uppercase;
    letter-spacing: var(--track-mid);
    font-weight: 700;
  }

  .note {
    max-inline-size: 70ch;
    margin: 0 0 1rem;
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.6;
  }

  .note strong {
    text-decoration: underline;
    text-underline-offset: 4px;
  }

  .note:last-child {
    margin-block-end: 0;
  }

  /* Definition rows — skills, experience, credentials. */
  .spec {
    display: grid;
    grid-template-columns: minmax(11rem, 16rem) minmax(0, 1fr);
    gap: 0;
    border-block-start: var(--rule) solid currentColor;
  }

  .spec__key {
    padding-block: 1rem 1rem;
    padding-inline-end: 1.25rem;
    border-block-end: var(--rule-hair) solid currentColor;
    font-size: var(--step--2);
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    font-weight: 700;
  }

  .spec__val {
    padding-block: 1rem;
    border-block-end: var(--rule-hair) solid currentColor;
    border-inline-start: var(--rule-hair) solid currentColor;
    padding-inline-start: 1.25rem;
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.65;
  }

  .spec__val p {
    margin-block-end: 0.75rem;
  }

  .spec__val a {
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
  }

  .spec__val a:hover {
    color: var(--accent);
  }

  .spec__val p:last-child {
    margin-block-end: 0;
  }

  .spec__val .chips {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem 0.5rem;
  }

  .spec__val .chips li {
    border: var(--rule-hair) solid currentColor;
    padding: 0.15rem 0.5rem;
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: var(--track-tight);
  }

  @media screen and (max-width: 40rem) {
    /* One column: a key and its value read as a single group, so the key
       drops its own hairline and the rule below the value becomes the only
       divider between groups. Without this the key's rule sits flush
       against the first bordered chip, and the two 1px lines merge. */
    .spec {
      grid-template-columns: minmax(0, 1fr);
    }

    .spec__key {
      padding-block: 1rem 0.5rem;
      border-block-end: 0;
    }

    .spec__val {
      border-inline-start: 0;
      padding-inline: 0;
      padding-block: 0 1rem;
    }
  }

  /* Bordered data table. */
  .table-wrap {
    overflow-x: auto;
    max-inline-size: 100%;
    margin-block-end: clamp(1.25rem, 3vw, 2rem);
  }

  table.rubric {
    inline-size: 100%;
    border-collapse: collapse;
    border: var(--rule) solid currentColor;
    font-size: var(--step-0);
  }

  table.rubric caption {
    text-align: start;
    font-size: var(--step--2);
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    color: var(--dim);
    padding-block-end: 0.625rem;
  }

  table.rubric th,
  table.rubric td {
    border: var(--rule) solid currentColor;
    padding: 0.875rem 1rem;
    text-align: start;
    vertical-align: top;
  }

  table.rubric th {
    text-transform: uppercase;
    letter-spacing: var(--track-mid);
    font-size: var(--step--2);
  }

  table.rubric tbody th {
    font-weight: 700;
    white-space: nowrap;
  }
}


/* ==========================================================================
   10  DOCUMENT PAGES (WRITEUPS AND BREACH REPORTS)
   ========================================================================== */

@layer components {
  .page {
    padding-block: clamp(2rem, 5vw, 3.5rem) clamp(1.75rem, 4vw, 3rem);
    border-block-end: var(--rule) solid currentColor;
  }

  .page__meta {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
    font-size: var(--step--2);
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    color: var(--dim);
    margin-block-end: clamp(1.125rem, 3vw, 2rem);
  }

  /* A repository path is one long token with no break opportunity of its own.
     Without this it sets the item's minimum size and pushes the row wider than
     a phone screen instead of wrapping. */
  .page__meta span {
    min-inline-size: 0;
    overflow-wrap: anywhere;
  }

  .page__title {
    font-size: var(--step-4);
    line-height: 0.95;
    letter-spacing: -0.03em;
    text-transform: uppercase;
  }

  .page__standfirst {
    max-inline-size: 60ch;
    margin-block-start: clamp(1rem, 2.5vw, 1.5rem);
    font-family: var(--font-sans);
    font-size: var(--step-1);
    line-height: 1.6;
    color: var(--dim);
  }

  .crumb {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-block-end: 1.25rem;
    font-size: var(--step--2);
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    text-decoration: none;
    color: var(--dim);
  }

  .crumb:hover {
    color: var(--ink);
  }

  .crumb::before {
    content: "\2190";
    font-size: 1rem;
    line-height: 1;
  }

  /* Prose reading voice. */
  .prose {
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.7;
    color: var(--ink);
  }

  .prose > * + * {
    margin-block-start: 1.125rem;
  }

  .prose a {
    text-decoration-color: var(--accent);
    text-decoration-thickness: 2px;
  }

  .prose a:hover {
    color: var(--accent);
  }

  .prose h2 {
    font-family: var(--font-mono);
    font-size: var(--step-2);
    text-transform: uppercase;
    margin-block-start: clamp(2rem, 4vw, 3rem);
    padding-block-end: 0.5rem;
    border-block-end: var(--rule) solid currentColor;
  }

  .prose h3 {
    font-family: var(--font-mono);
    font-size: var(--step-1);
    text-transform: uppercase;
    letter-spacing: var(--track-tight);
    margin-block-start: 1.75rem;
  }

  .prose h4 {
    font-family: var(--font-mono);
    font-size: var(--step-0);
    text-transform: uppercase;
    letter-spacing: var(--track-mid);
    margin-block-start: 1.5rem;
  }

  .prose p,
  .prose li {
    max-inline-size: var(--measure);
  }

  .prose ul,
  .prose ol {
    padding-inline-start: 1.35rem;
  }

  .prose li + li {
    margin-block-start: 0.4rem;
  }

  .prose code {
    font-family: var(--font-mono);
    font-size: 0.92em;
    border: var(--rule-hair) solid currentColor;
    padding: 0.05em 0.35em;
    overflow-wrap: anywhere;
  }

  .prose pre {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    line-height: 1.6;
    border: var(--rule) solid currentColor;
    padding: 1rem 1.125rem;
    overflow-x: auto;
    white-space: pre;
  }

  .prose pre code {
    border: 0;
    padding: 0;
    font-size: inherit;
  }

  .prose blockquote {
    border-inline-start: var(--rule) solid currentColor;
    padding-inline-start: 1.25rem;
    color: var(--dim);
    font-style: normal;
  }

  .prose hr {
    border: 0;
    border-block-start: var(--rule-hair) solid currentColor;
    margin-block: 2rem;
  }

  .prose figure {
    margin-block: 1.75rem;
    max-inline-size: 30rem;
  }

  .prose figure img {
    display: block;
    inline-size: 100%;
    border: var(--rule-hair) solid currentColor;
  }

  .prose figcaption {
    margin-block-start: 0.5rem;
    font-family: var(--font-mono);
    font-size: var(--step--2);
    letter-spacing: var(--track-tight);
    color: var(--dim);
  }

  /* Flag disclosure — native <details>, no JavaScript. */
  .flag {
    border: var(--rule) solid currentColor;
    margin-block: 1rem;
  }

  .flag > summary {
    cursor: pointer;
    padding: 0.75rem 1rem;
    font-family: var(--font-mono);
    font-size: var(--step--1);
    letter-spacing: var(--track-mid);
    text-transform: uppercase;
    font-weight: 700;
    color: var(--accent);
    list-style: none;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
  }

  .flag > summary::-webkit-details-marker {
    display: none;
  }

  .flag > summary::after {
    content: "+";
    font-size: 1.1rem;
    line-height: 1;
  }

  .flag[open] > summary::after {
    content: "\2212";
  }

  .flag[open] > summary {
    border-block-end: var(--rule-hair) solid currentColor;
  }

  .flag > summary:hover {
    background: var(--accent);
    color: var(--paper);
  }

  .flag__body {
    padding: 1rem;
  }

  .flag__body code {
    font-family: var(--font-mono);
    font-size: var(--step-0);
    font-weight: 700;
    color: var(--accent);
    overflow-wrap: anywhere;
  }

  /* Source / provenance block. */
  .provenance {
    margin-block-start: clamp(2rem, 4vw, 3rem);
    border-block-start: var(--rule) solid currentColor;
    padding-block-start: 1.25rem;
    font-size: var(--step--1);
    color: var(--dim);
  }

  .provenance p {
    margin-block-end: 0.4rem;
  }

  .provenance a {
    color: inherit;
  }
}


/* ==========================================================================
   11  RESUME
   ========================================================================== */

@layer components {
  .resume__intro {
    max-inline-size: 66ch;
    font-family: var(--font-sans);
    font-size: var(--step-1);
    line-height: 1.6;
    color: var(--dim);
  }

  .resume__contact {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem 1.5rem;
    margin-block-start: 1.5rem;
    font-size: var(--step--1);
    letter-spacing: var(--track-mid);
    text-transform: uppercase;
  }

  .resume__contact a {
    text-decoration: none;
    border-block-end: var(--rule-hair) solid currentColor;
  }

  .resume__contact a:hover {
    text-decoration: underline;
  }
}


/* ==========================================================================
   12  PROJECT PAGE
   ========================================================================== */

@layer components {
  .telegram {
    border: var(--rule) solid currentColor;
    max-inline-size: 30rem;
    margin-block-start: 1.5rem;
  }

  .telegram__bar {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.625rem 0.875rem;
    border-block-end: var(--rule) solid currentColor;
  }

  .telegram__bar span {
    font-size: var(--step--2);
    letter-spacing: var(--track-mid);
    text-transform: uppercase;
    color: var(--dim);
  }

  .telegram__body {
    padding: 1rem 1.125rem;
  }

  .telegram__title {
    font-weight: 700;
    font-size: var(--step-0);
    margin-block-end: 0.75rem;
  }

  .telegram__msg {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    line-height: 1.65;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }

  .telegram__stamp {
    margin-block-start: 0.75rem;
    font-size: var(--step--2);
    color: var(--dim);
    text-align: end;
  }

  .flagged {
    display: inline-block;
    border: var(--rule) solid currentColor;
    padding: 0.3rem 0.625rem;
    font-size: var(--step--2);
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    font-weight: 700;
  }
}


/* ==========================================================================
   13  FOOTER
   ========================================================================== */

@layer components {
  .foot {
    padding-block: clamp(2.25rem, 6vw, 4rem);
  }

  .foot .wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 1.75rem 2.5rem;
    justify-content: space-between;
  }

  .foot__col {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    font-size: var(--step--1);
    color: var(--dim);
    min-inline-size: 12rem;
  }

  .foot__col--icons {
    min-inline-size: 15rem;
  }

  .foot__col p {
    margin: 0;
  }

  .foot__mark {
    font-size: 1.2rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    color: var(--ink);
  }

  .foot__col--alias > span:last-child {
    color: var(--accent);
    font-weight: 700;
    letter-spacing: var(--track-mid);
  }

  .foot__col > span:not(.foot__mark) {
    letter-spacing: var(--track-wide);
    text-transform: uppercase;
    font-size: var(--step--2);
  }

  .foot__icons {
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
    margin-block-start: 0.25rem;
  }

  .icon-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    border: var(--rule) solid currentColor;
    color: var(--ink);
    text-decoration: none;
  }

  .icon-link:hover {
    background: var(--accent);
    color: var(--paper);
  }

  .icon-link svg {
    inline-size: 1.1rem;
    block-size: 1.1rem;
  }
}


/* ==========================================================================
   14  UTILITIES
   ========================================================================== */

@layer utilities {
  .visually-hidden {
    position: absolute;
    clip-path: inset(50%);
    overflow: hidden;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    white-space: nowrap;
  }

  .stack-sm > * + * {
    margin-block-start: 0.75rem;
  }

  .stack > * + * {
    margin-block-start: 1.25rem;
  }

  .stack-lg > * + * {
    margin-block-start: clamp(1.5rem, 3vw, 2.25rem);
  }

  .mt-lg {
    margin-block-start: clamp(1.5rem, 3vw, 2.25rem);
  }

  .muted {
    color: var(--dim);
  }

  .link-plain {
    text-decoration: none;
    border-block-end: var(--rule-hair) solid currentColor;
  }

  .link-plain:hover {
    text-decoration: underline;
  }

  .rule {
    border: 0;
    border-block-start: var(--rule) solid currentColor;
    margin-block: 0;
  }

  .rule--hair {
    border-block-start: var(--rule-hair) solid currentColor;
  }

  .print-hint {
    margin-block-start: 1.5rem;
    font-size: var(--step--1);
    color: var(--dim);
  }
}


/* ==========================================================================
   15  PRINT
   ========================================================================== */

@layer print {
  @media print {
    :root {
      --paper: #ffffff;
      --ink: #000000;
      --dim: #3d3d3d;
      --accent: #9e3a20;
      --rule: 1px;
      --rule-hair: 1px;
      color-scheme: light;
    }

    html {
      scroll-behavior: auto;
    }

    body {
      background: #fff;
      color: #000;
      font-size: 10.5pt;
      line-height: 1.45;
    }

    .bar,
    .skip,
    .foot,
    .no-print {
      display: none !important;
    }

    .band,
    .page,
    .hero {
      border: 0;
      padding-block: 0;
    }

    .band--invert,
    .band--warm {
      background: transparent;
      color: #000;
    }

    .band {
      margin-block-end: 10pt;
    }

    .band__head h2,
    .page__title,
    .hero__title {
      font-size: 16pt;
    }

    .band__lede,
    .resume__intro,
    .page__standfirst {
      font-size: 11.5pt;
    }

    .prose {
      font-size: 10.5pt;
    }

    .band__lede {
      max-inline-size: none;
    }

    .hero__title {
      line-height: 1;
    }

    .spec {
      grid-template-columns: 10rem minmax(0, 1fr);
    }

    .spec__val,
    .spec__key {
      padding-block: 0.4rem;
    }

    .cell,
    .row,
    .spec__key,
    .spec__val {
      break-inside: avoid;
    }

    .prose h2,
    .prose h3 {
      break-after: avoid;
    }

    .resume__contact a::after {
      content: "";
    }

    a {
      color: #000;
      text-decoration: none;
    }

    .resume__contact a,
    .provenance a {
      text-decoration: underline;
    }

    @page {
      margin: 14mm 14mm 16mm;
    }
  }
}
