/* =========================================================================
   paulgschwendtner.com shared stylesheet ("Executive editorial")

   Each page loads, in <head>:
     1. Google Fonts: Geist (body/UI) and Newsreader (display serif)
     2. <link rel="stylesheet" href="site.css">
     3. <script src="site.js"></script>   (adds .js to <html>, wires the menu)

   Contents
     01 Tokens (light, dark, forced themes)
     02 Reset and base elements
     03 Typography
     04 Layout primitives (container, section, split)
     05 Accessibility helpers (skip link, focus, visually hidden)
     06 Site header and navigation
     07 Buttons and text links
     08 Icons
     09 Hero
     09b Page header (inner pages)
     10 Build columns (home page)
     11 Build list (rows of links)
     12 Dash list (bullets)
     13 Entries (experience timeline)
     14 Term grid
     15 Cert groups
     16 Cards
     17 Quotes
     18 Contact band
     19 Site footer
     20 Utilities
     21 Motion and reduced motion
     22 Print
     23 Page: home (index.html)
     24 Page: projects (projects.html)
     25 Page: portfolio (portfolio.html)
     26 Page: daily brief (daily-brief.html)
     27 Page: inspection app case studies

   Other pages: append a new numbered "Page: <name>" section at the end of
   this file and prefix page-only classes with the page name.
   ========================================================================= */


/* -------------------------------------------------------------------------
   01 Tokens
   ------------------------------------------------------------------------- */
:root {
  color-scheme: light dark;

  /* Color (light) */
  --bg: #FFFFFF;
  --bg-band: #F4F6F9;          /* tinted bands: contact, footer */
  --bg-glass: rgba(255, 255, 255, 0.86); /* sticky header over content */
  --ink: #0E1B2C;              /* headings, primary text */
  --ink-2: #2B3A4F;            /* body text in lists */
  --muted: #4A5768;            /* secondary text, eyebrows */
  --line: #DDE2E8;             /* hairlines */
  --line-band: #D3DAE2;        /* hairlines on --bg-band */
  --line-strong: #B9C2CE;      /* resting underline on text links */
  --accent: #1D4ED8;
  --accent-ink: #FFFFFF;       /* text on solid accent */
  --btn-bg: var(--ink);        /* primary button */
  --btn-ink: var(--bg);
  --btn-bg-hover: var(--accent);
  --btn-ink-hover: var(--accent-ink);

  /* Type */
  --font-serif: "Newsreader", Georgia, "Times New Roman", serif;
  --font-sans: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --fs-display: clamp(40px, 6vw, 68px);
  --fs-h2: clamp(32px, 3.6vw, 46px);
  --fs-h3: clamp(24px, 2.4vw, 30px);
  --fs-statement: clamp(22px, 2.5vw, 30px);
  --fs-lead: clamp(17px, 1.5vw, 18px);
  --fs-body: 16px;
  --fs-small: 14px;
  --fs-eyebrow: 12px;

  /* Space and shape */
  --max: 1120px;               /* content width inside the gutters */
  --gutter: clamp(20px, 4vw, 40px);
  --space-section: clamp(64px, 9vw, 120px);
  --label-col: 220px;
  --col-gap: 48px;
  --header-h: 64px;
  --radius: 4px;
  --radius-img: 6px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0B1220;
    --bg-band: #111A2B;
    --bg-glass: rgba(11, 18, 32, 0.86);
    --ink: #E7ECF3;
    --ink-2: #C6CFDB;
    --muted: #9DA9B8;
    --line: #243149;
    --line-band: #2A3852;
    --line-strong: #3E4E6B;
    --accent: #8AB4FF;
    --accent-ink: #0B1220;
    --btn-bg: var(--accent);
    --btn-ink: var(--accent-ink);
    --btn-bg-hover: var(--ink);
    --btn-ink-hover: var(--bg);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0B1220;
  --bg-band: #111A2B;
  --bg-glass: rgba(11, 18, 32, 0.86);
  --ink: #E7ECF3;
  --ink-2: #C6CFDB;
  --muted: #9DA9B8;
  --line: #243149;
  --line-band: #2A3852;
  --line-strong: #3E4E6B;
  --accent: #8AB4FF;
  --accent-ink: #0B1220;
  --btn-bg: var(--accent);
  --btn-ink: var(--accent-ink);
  --btn-bg-hover: var(--ink);
  --btn-ink-hover: var(--bg);
}

:root[data-theme="light"] { color-scheme: light; }


/* -------------------------------------------------------------------------
   02 Reset and base elements
   ------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

h1, h2, h3, h4, h5, h6 {
  color: var(--ink);
  font-weight: 600;
  line-height: 1.2;
}

/* Classed lists are layout components: no bullets, no indent.
   :where() keeps this at zero specificity so component margins win. */
:where(ul[class], ol[class]) {
  list-style: none;
  margin: 0;
  padding: 0;
}

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

svg { flex: none; }

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  text-decoration-color: var(--line-strong);
}

a:hover {
  color: var(--accent);
  text-decoration-color: currentColor;
}

button {
  font: inherit;
  color: inherit;
}

strong,
b {
  font-weight: 600;
  color: var(--ink);
}

/* Keeps anchor jumps and keyboard focus clear of the sticky header */
html { scroll-padding-top: calc(var(--header-h) + 16px); }


/* -------------------------------------------------------------------------
   03 Typography
   ------------------------------------------------------------------------- */

/* Small uppercase label with a short accent rule */
.eyebrow {
  font-family: var(--font-sans);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.eyebrow::before {
  content: "";
  display: inline-block;
  width: 20px;
  height: 1px;
  margin-right: 12px;
  vertical-align: middle;
  background: var(--accent);
}

/* Big serif page title (one per page, usually the h1) */
.display {
  font-family: var(--font-serif);
  font-size: var(--fs-display);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -0.022em;
  color: var(--ink);
}

/* Section heading (h2) */
.section-title {
  font-family: var(--font-serif);
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
}

/* Heading inside a section (h3) */
.subsection-title {
  font-family: var(--font-serif);
  font-size: var(--fs-h3);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--ink);
}

/* Intro paragraph under a heading */
.lead {
  max-width: 38rem;
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--muted);
}

.section-title + .lead,
.subsection-title + .lead { margin-top: 16px; }

/* Large serif prose, used for one standout paragraph */
.statement {
  max-width: 26em;
  font-family: var(--font-serif);
  font-size: var(--fs-statement);
  font-weight: 400;
  line-height: 1.36;
  letter-spacing: -0.012em;
  color: var(--ink);
}

/* Running text */
.prose {
  max-width: 40rem;
  font-size: 17px;
  line-height: 1.7;
  color: var(--ink-2);
}

.prose > * + * { margin-top: 1.1em; }

.meta {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--muted);
}


/* -------------------------------------------------------------------------
   04 Layout primitives
   ------------------------------------------------------------------------- */

/* Centered column: --max of content plus the gutters */
.container {
  width: 100%;
  max-width: calc(var(--max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* A page section: <section class="section"><div class="container"><div class="section-inner"> */
.section-inner {
  border-top: 1px solid var(--line);
  padding-block: var(--space-section);
}

.section--flush .section-inner { border-top: 0; }

/* Tinted full-bleed band */
.section--band {
  background: var(--bg-band);
  border-top: 1px solid var(--line);
}

.section--band .section-inner { border-top: 0; }

/* Two columns: narrow label column (eyebrow) + content column.
   Use exactly two children: the label, then the body. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: 16px;
}

@media (min-width: 800px) {
  .split {
    grid-template-columns: var(--label-col) minmax(0, 1fr);
    column-gap: var(--col-gap);
    align-items: baseline;
  }
}

.split-label,
.split-body { min-width: 0; }

/* Heading row above full-width content (lists that span both columns) */
.section-head { margin-bottom: clamp(32px, 4vw, 44px); }

/* Vertical rhythm helper: spaces direct children evenly */
.stack > * + * { margin-top: var(--stack-space, 16px); }


/* -------------------------------------------------------------------------
   05 Accessibility helpers
   ------------------------------------------------------------------------- */
.skip-link {
  position: absolute;
  top: 12px;
  left: 16px;
  z-index: 100;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  border-radius: var(--radius);
  background: var(--btn-bg);
  color: var(--btn-ink);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  transform: translateY(calc(-100% - 24px));
}

.skip-link:focus,
.skip-link:hover {
  color: var(--btn-ink);
  transform: none;
}

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

.btn:focus-visible,
.nav-toggle:focus-visible,
.skip-link:focus-visible { border-radius: var(--radius); }

main:focus { outline: none; }

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* -------------------------------------------------------------------------
   06 Site header and navigation
   Markup:
   <header class="site-header"><div class="container header-bar">
     <a class="brand" href="...">Name</a>
     <nav class="site-nav" aria-label="Primary">
       <button class="nav-toggle" type="button" aria-expanded="false" aria-controls="site-menu">Menu</button>
       <ul class="nav-links" id="site-menu"> <li><a href="...">...</a></li> </ul>
     </nav>
   </div></header>
   The toggle only shows, and the links only collapse, under .js (site.js).
   ------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .site-header {
    background: var(--bg-glass);
    -webkit-backdrop-filter: saturate(1.4) blur(14px);
    backdrop-filter: saturate(1.4) blur(14px);
  }
}

.header-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  column-gap: 32px;
  padding-block: 10px;
}

.brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-serif);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -0.012em;
  color: var(--ink);
  text-decoration: none;
}

/* Very narrow phones (320px): keep the name and the Menu button on one row */
@media (max-width: 359px) {
  .header-bar { column-gap: 16px; }
  .brand { font-size: 19px; }
}

.nav-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: clamp(16px, 2vw, 26px);
}

.nav-links a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
}

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

.nav-links a[aria-current="page"] {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 8px;
}

/* Emphasized last link (for example "My Portfolio" with an arrow) */
.nav-links .nav-cta { font-weight: 600; }

.nav-cta .icon { transition: transform 0.2s var(--ease); }
.nav-cta:hover .icon { transform: translateX(2px); }

.nav-toggle { display: none; }

@media (max-width: 859px) {
  /* Without JS the links wrap under the name; keep that tall header unsticky */
  html:not(.js) .site-header { position: static; }

  .js .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: transparent;
    color: var(--ink);
    font-size: 14.5px;
    font-weight: 500;
    cursor: pointer;
  }

  .js .nav-toggle:hover { border-color: var(--ink); }

  .nav-toggle .icon-close { display: none; }
  .nav-toggle[aria-expanded="true"] .icon-open { display: none; }
  .nav-toggle[aria-expanded="true"] .icon-close { display: inline-block; }

  .js .nav-links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    padding: 4px var(--gutter) 16px;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
  }

  .js .nav-toggle[aria-expanded="false"] + .nav-links { display: none; }

  .js .nav-links li + li { border-top: 1px solid var(--line); }

  .js .nav-links a {
    display: flex;
    min-height: 52px;
    font-size: 16px;
  }
}


/* -------------------------------------------------------------------------
   07 Buttons and text links
   ------------------------------------------------------------------------- */
.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 22px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s, border-color 0.2s, color 0.2s;
}

.btn .icon { transition: transform 0.2s var(--ease); }
.btn:hover .icon { transform: translateX(2px); }

/* Solid: ink in light mode, accent in dark mode */
.btn--primary {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-ink);
}

.btn--primary:hover {
  background: var(--btn-bg-hover);
  border-color: var(--btn-bg-hover);
  color: var(--btn-ink-hover);
}

/* 1px outline */
.btn--secondary {
  background: transparent;
  border-color: var(--ink);
  color: var(--ink);
}

.btn--secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Underlined text action that keeps a 48px target */
.btn--link {
  gap: 6px;
  padding: 0 8px;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
}

.btn--link .icon { color: var(--accent); }
.btn--link:hover { color: var(--accent); text-decoration-color: currentColor; }
.btn--link:hover .icon { transform: translate(2px, -2px); }

/* Inline text link with a trailing arrow */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 5px;
}

.link-arrow .icon {
  color: var(--accent);
  transition: transform 0.2s var(--ease);
}

.link-arrow:hover .icon { transform: translateX(2px); }


/* -------------------------------------------------------------------------
   08 Icons
   Inline stroke SVGs: width/height attributes set the size,
   stroke="currentColor", aria-hidden="true", focusable="false".
   ------------------------------------------------------------------------- */
.icon {
  display: inline-block;
  flex: none;
  vertical-align: middle;
}

.icon-accent { color: var(--accent); }


/* -------------------------------------------------------------------------
   09 Hero
   ------------------------------------------------------------------------- */
.hero { padding-block: clamp(48px, 7vw, 96px) clamp(48px, 6vw, 80px); }

.hero-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: clamp(40px, 6vw, 72px);
  row-gap: 48px;
}

.hero-text {
  flex: 1.6 1 460px;
  min-width: 0;
}

.hero-name { margin-top: 20px; }

.hero-title {
  margin-top: 20px;
  font-size: clamp(17px, 1.6vw, 20px);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.hero-cred {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--muted);
}

.hero-cred .icon { color: var(--accent); }

.hero-actions {
  max-width: 560px;
  margin-top: 32px;
  padding-top: 32px;
  border-top: 1px solid var(--line);
  container-type: inline-size;
}

/* Under about 500px the LinkedIn text link wraps below the buttons.
   Drop its leading padding there so it lines up with the left edge. */
@container (max-width: 499.98px) {
  .hero-actions .btn--link {
    padding-inline-start: 0;
    border-inline-start-width: 0;
  }
}

.hero-photo {
  flex: 1 1 300px;
  min-width: 0;
  max-width: 400px;
}

.hero-photo img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 28%;
  border-radius: var(--radius-img);
  background: var(--bg-band);
}

@media (max-width: 720px) {
  .hero-photo { max-width: 340px; }
}

/* Tablets (photo stacks under the buttons): keep it from filling the first screen */
@media (min-width: 600px) and (max-width: 799px) {
  .hero-photo { max-width: 260px; }
}

/* Phones: a small round photo above the name, like a profile header,
   and a tighter rhythm so the hero fits on the first screen */
@media (max-width: 599px) {
  .hero { padding-block: 28px 40px; }
  .hero-grid { row-gap: 20px; }
  .hero-photo {
    order: -1;
    flex: none;
    width: 96px;
  }
  .hero-photo img {
    aspect-ratio: 1 / 1;
    object-position: 50% 22%;
    border-radius: 50%;
  }
  .hero-name { margin-top: 12px; }
  .hero-title { margin-top: 14px; }
  .hero-actions {
    margin-top: 20px;
    padding-top: 20px;
  }
}


/* -------------------------------------------------------------------------
   09b Page header (inner pages: portfolio, projects, daily brief)
   <section class="page-head"><div class="container"><div class="split">
     <div class="split-label"><p class="eyebrow">Label</p></div>
     <div class="split-body"><h1 class="display">Title</h1><p class="lead">...</p></div>
   </div></div></section>
   Same grid as the sections below it, so the title lines up with the content.
   ------------------------------------------------------------------------- */
.page-head { padding-block: clamp(48px, 7vw, 96px) clamp(40px, 5vw, 72px); }

.page-head .lead { margin-top: 24px; }


/* -------------------------------------------------------------------------
   10 Build columns: one column per kind of build (home page)
   <div class="build-cols"><div class="build-col">
     <h3 class="build-col-title">...</h3><p class="build-col-text">...</p>
     <p class="build-stack">Tool · Tool</p><ul class="build-list">...</ul>
   </div></div>
   Stacked on phones, 3 across from 900px.
   ------------------------------------------------------------------------- */
.build-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 40px;
}

/* Each column shares the grid's rows (title, text, tools, links), so the link lists
   line up across columns even when one pitch wraps to an extra line. */
@media (min-width: 900px) {
  .build-cols {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    row-gap: 0;
  }

  .build-col {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    align-content: start;
  }

  /* A shorter list keeps its own height, so its bottom hairline sits under its last link */
  .build-list { align-self: start; }
}

.build-col {
  min-width: 0;
  border-top: 2px solid var(--accent);
  padding-top: 18px;
}

.build-col-title {
  font-family: var(--font-sans);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.build-col-text {
  margin-top: 8px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
}

.build-stack {
  margin-top: 10px;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-2);
}

.build-more { margin-top: clamp(28px, 4vw, 40px); }


/* -------------------------------------------------------------------------
   11 Build list: hairline rows of links inside a build column
   <ul class="build-list"><li><a class="build-link" href="...">
     <span class="build-name">Name</span> <svg class="icon build-arrow">...</svg>
   </a></li></ul>
   ------------------------------------------------------------------------- */
.build-list {
  margin-top: 16px;
  border-bottom: 1px solid var(--line);
}

.build-list > li { border-top: 1px solid var(--line); }

.build-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 52px;
  padding-block: 12px;
  color: var(--ink);
  text-decoration: none;
}

.build-name {
  font-family: var(--font-serif);
  font-size: clamp(19px, 1.8vw, 21px);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

.build-arrow {
  color: var(--accent);
  transition: transform 0.2s var(--ease);
}

.build-link:hover { color: var(--accent); }
.build-link:hover .build-arrow { transform: translate(2px, -2px); }


/* -------------------------------------------------------------------------
   12 Dash list: bullets drawn as short accent rules
   ------------------------------------------------------------------------- */
.dash-list {
  display: grid;
  row-gap: 12px;
}

.dash-list > li {
  position: relative;
  padding-left: 26px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-2);
}

.dash-list > li::before {
  content: "";
  position: absolute;
  top: 0.8em;
  left: 0;
  width: 12px;
  height: 1px;
  background: var(--accent);
}


/* -------------------------------------------------------------------------
   13 Entries: experience timeline
   <ol class="entries"><li class="entry split">
     <div class="entry-aside"><p class="entry-org">Company</p>
       <p class="entry-meta"><span>Dates</span><span class="sep" aria-hidden="true"> · </span><span>Place</span></p></div>
     <div class="entry-body"><h3 class="entry-role">Role</h3>
       <p class="entry-desc">...</p><ul class="dash-list">...</ul></div>
   </li></ol>
   Meta parts sit on one line on phones and stack in the label column on desktop.
   ------------------------------------------------------------------------- */
.entries { border-bottom: 0; }

.entry {
  border-top: 1px solid var(--line);
  padding-block: clamp(28px, 4vw, 40px);
}

.entry-org {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.2vw, 26px);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.012em;
  color: var(--ink);
}

.entry-meta {
  margin-top: 8px;
  font-size: var(--fs-small);
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.entry-meta > span:first-child {
  font-weight: 500;
  color: var(--ink-2);
}

.entry-role {
  font-family: var(--font-sans);
  font-size: clamp(18px, 1.6vw, 19px);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.entry-desc {
  max-width: 46rem;
  margin-top: 12px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--muted);
}

.entry-body > .dash-list {
  max-width: 46rem;
  margin-top: 16px;
}

.entry-desc + .dash-list { margin-top: 20px; }

@media (min-width: 800px) {
  .entry-meta { margin-top: 10px; }
  .entry-meta > span:not(.sep) { display: block; }
  .entry-meta > .sep { display: none; }
}


/* -------------------------------------------------------------------------
   14 Term grid: short ruled items (skills, keywords)
   ------------------------------------------------------------------------- */
.term-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(20px, 3vw, 32px);
}

.term-grid > li {
  border-top: 1px solid var(--line);
  padding-block: 14px;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink);
}

@media (min-width: 800px) {
  .term-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .term-grid > li { font-size: 16px; }
}


/* -------------------------------------------------------------------------
   15 Cert groups: credentials grouped by issuer
   <div class="cert-groups"><div class="cert-group">
     <h4 class="cert-issuer">Issuer</h4><ul class="cert-list"><li>Name</li></ul>
   </div></div>
   ------------------------------------------------------------------------- */
.cert-groups {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr));
  column-gap: 32px;
  row-gap: 36px;
}

.cert-group {
  border-top: 1px solid var(--line);
  padding-top: 16px;
}

.cert-issuer {
  font-family: var(--font-sans);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.cert-list {
  display: grid;
  row-gap: 10px;
  margin-top: 12px;
}

.cert-list > li {
  font-size: 15.5px;
  line-height: 1.45;
  color: var(--ink);
}


/* -------------------------------------------------------------------------
   16 Cards: hairline-topped blocks, no boxes or shadows
   <ul class="card-grid card-grid--2"><li class="card">
     <svg class="icon card-icon">...</svg>
     <h3 class="card-title">...</h3> <p class="card-sub">...</p>
     <p class="card-text">...</p> <p class="card-meta">...</p>
   </li></ul>
   ------------------------------------------------------------------------- */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  column-gap: 40px;
  row-gap: 36px;
}

@media (min-width: 640px) {
  .card-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.card {
  min-width: 0;
  border-top: 1px solid var(--line);
  padding-top: 20px;
}

.card-icon {
  display: block;
  margin-bottom: 14px;
  color: var(--accent);
}

.card-title {
  font-family: var(--font-sans);
  font-size: 17px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.005em;
  color: var(--ink);
}

/* Serif variant for names of schools, organizations, awards */
.card-title--serif {
  font-family: var(--font-serif);
  font-size: clamp(21px, 2vw, 24px);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.card-sub {
  margin-top: 8px;
  font-size: 15.5px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-2);
}

.card-text {
  margin-top: 8px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--muted);
}

.card-meta {
  margin-top: 10px;
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}


/* -------------------------------------------------------------------------
   17 Quotes
   <figure class="quote"><blockquote class="quote-text"><p>...</p></blockquote>
     <figcaption class="quote-cite"><span class="quote-name">Name</span>
     <span class="quote-role">Title</span></figcaption></figure>
   ------------------------------------------------------------------------- */
.quote {
  border-top: 1px solid var(--line);
  padding-block: clamp(28px, 4vw, 40px);
}

.quote:last-child { padding-bottom: 0; }

.quote-text {
  max-width: 40rem;
  font-family: var(--font-serif);
  font-size: clamp(19px, 1.9vw, 22px);
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.quote-text::before {
  content: "\201C";
  content: "\201C" / "";
  display: block;
  height: 0.5em;
  margin-bottom: 6px;
  font-family: var(--font-serif);
  font-size: 64px;
  line-height: 1;
  color: var(--accent);
}

.quote-cite {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 20px;
}

.quote-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}

.quote-role {
  font-size: var(--fs-small);
  color: var(--muted);
}


/* -------------------------------------------------------------------------
   18 Contact band
   ------------------------------------------------------------------------- */
.contact-title {
  font-family: var(--font-serif);
  font-size: clamp(44px, 6vw, 76px);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.025em;
  color: var(--ink);
}

.contact-title + .lead { margin-top: 20px; }

.contact-list {
  max-width: 720px;
  margin-top: 40px;
  border-bottom: 1px solid var(--line-band);
}

.contact-list > li { border-top: 1px solid var(--line-band); }

.contact-link {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-block: 20px;
  color: var(--ink);
  text-decoration: none;
}

.contact-link > .icon:first-child { color: var(--accent); }

.contact-text {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

.contact-arrow { transition: transform 0.2s var(--ease); }
.contact-link:hover { color: var(--accent); }
.contact-link:hover .contact-arrow { transform: translateX(3px); }
.contact-link:hover .contact-arrow--out { transform: translate(2px, -2px); }


/* -------------------------------------------------------------------------
   19 Site footer
   ------------------------------------------------------------------------- */
.site-footer { background: var(--bg-band); }

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px 32px;
  padding-block: 20px 28px;
  border-top: 1px solid var(--line-band);
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
}

.footer-inner p { text-wrap: pretty; }

.footer-inner a {
  font-weight: 500;
  color: var(--ink-2);
}

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


/* -------------------------------------------------------------------------
   20 Utilities
   ------------------------------------------------------------------------- */
.serif { font-family: var(--font-serif); }
.muted { color: var(--muted); }
.accent-text { color: var(--accent); }
.measure { max-width: 40rem; }
.nowrap { white-space: nowrap; }
.mt-0 { margin-top: 0 !important; }
.mt-s { margin-top: 16px; }
.mt-m { margin-top: 32px; }
.mt-l { margin-top: clamp(48px, 6vw, 72px); }


/* -------------------------------------------------------------------------
   21 Motion and reduced motion
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }

  .hero-text,
  .hero-photo,
  .page-head .split { animation: rise-in 0.5s var(--ease) both; }

  .hero-photo { animation-delay: 0.06s; }

  @keyframes rise-in {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
  }
}

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


/* -------------------------------------------------------------------------
   22 Print
   ------------------------------------------------------------------------- */
@media print {
  .site-header { position: static; }
  .skip-link,
  .nav-toggle,
  .js .nav-toggle { display: none; }
  .section-inner { padding-block: 32px; }
  .case-shot, .case-table tr, .case-facts > div { break-inside: avoid; }
  .btn--primary { background: none; color: var(--ink); border: 1px solid currentColor; }
  h2, .split-label { break-after: avoid; }
}


/* -------------------------------------------------------------------------
   23 Page: home (index.html)
   ------------------------------------------------------------------------- */
.home-about .prose { margin-top: clamp(32px, 4vw, 44px); }

.home-about .statement + p { margin-top: 1.4em; }

.home-focus { margin-top: clamp(40px, 5vw, 56px); }

.home-skills .term-grid { margin-top: clamp(32px, 4vw, 40px); }

.home-skills .subsection-title { margin-top: clamp(56px, 7vw, 80px); }

.home-skills .cert-groups { margin-top: 28px; }

.home-grid { margin-top: clamp(32px, 4vw, 40px); }

.home-quotes { margin-top: clamp(32px, 4vw, 40px); }


/* -------------------------------------------------------------------------
   24 Page: projects (projects.html)
   A .page-head, then one section per company:
   <section class="section projects-group"><div class="container">
     <div class="section-inner split">
       <div class="split-label projects-label"><h2 class="projects-company">Company</h2></div>
       <div class="split-body"><ul class="projects-list"><li class="projects-item">
         <h3 class="projects-title">...</h3><p class="projects-desc">...</p>
       </li></ul></div>
   </div></div></section>
   The company name stays in view (sticky) beside its list on desktop.
   ------------------------------------------------------------------------- */
.projects-company {
  font-family: var(--font-serif);
  font-size: clamp(30px, 3vw, 38px);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.018em;
  color: var(--ink);
}

@media (max-width: 799px) {
  .projects-label { padding-bottom: 8px; }
}

@media (min-width: 800px) {
  .projects-label {
    position: sticky;
    top: calc(var(--header-h) + 32px);
  }
}

.projects-item + .projects-item {
  margin-top: 24px;
  padding-top: 24px;
  border-top: 1px solid var(--line);
}

.projects-title {
  font-family: var(--font-sans);
  font-size: clamp(17px, 1.5vw, 18px);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -0.008em;
  color: var(--ink);
}

.projects-desc {
  max-width: 46rem;
  margin-top: 8px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}


/* -------------------------------------------------------------------------
   25 Page: portfolio (portfolio.html)
   A .page-head, then one .portfolio-group per category: the category (h2)
   sits in the label column, its builds in the body column as a numbered list.
   Each title link stretches over its whole row, so the row is the target.
   ------------------------------------------------------------------------- */
.portfolio-groups {
  counter-reset: portfolio;
  padding-bottom: var(--space-section);
}

.portfolio-group {
  border-top: 1px solid var(--line);
  padding-block: clamp(20px, 3vw, 32px);
}

.portfolio-group:last-child { border-bottom: 1px solid var(--line); }

.portfolio-group-icon {
  display: block;
  margin-bottom: 14px;
  color: var(--accent);
}

.portfolio-group-title {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.2vw, 26px);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.012em;
  color: var(--ink);
}

.portfolio-item {
  --portfolio-title-size: clamp(23px, 2.3vw, 28px);
  position: relative;
  counter-increment: portfolio;
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 20px;
  column-gap: 14px;
  align-items: baseline;
  padding-block: 22px;
}

.portfolio-item + .portfolio-item { border-top: 1px solid var(--line); }

.portfolio-item::before {
  content: counter(portfolio, decimal-leading-zero);
  content: counter(portfolio, decimal-leading-zero) / "";
  grid-column: 1;
  grid-row: 1;
  font-family: var(--font-serif);
  font-size: 17px;
  line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--accent);
}

.portfolio-item > * { grid-column: 2; }

.portfolio-item > .portfolio-arrow {
  grid-column: 3;
  grid-row: 1;
  align-self: start;
  /* centered on the first line of the title */
  margin-top: calc((var(--portfolio-title-size) * 1.2 - 20px) / 2);
  color: var(--muted);
  transition: transform 0.2s var(--ease), color 0.2s;
}

.portfolio-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 14px;
  row-gap: 8px;
}

.portfolio-title {
  text-wrap: balance;
  font-family: var(--font-serif);
  font-size: var(--portfolio-title-size);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.012em;
  color: var(--ink);
}

.portfolio-link {
  color: inherit;
  text-decoration: none;
}

/* The link covers the whole row */
.portfolio-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.portfolio-link:focus-visible { outline: none; }

.portfolio-link:focus-visible::after {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius);
}

.portfolio-badge {
  position: relative;
  top: -0.2em;
  display: inline-block;
  padding: 3px 8px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--muted);
}

.portfolio-host {
  margin-top: 6px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
}

.portfolio-desc {
  max-width: 40rem;
  margin-top: 10px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}

.portfolio-item:hover .portfolio-title { color: var(--accent); }

.portfolio-item:hover .portfolio-arrow {
  color: var(--accent);
  transform: translate(2px, -2px);
}

@media (max-width: 799px) {
  .portfolio-item:first-child { padding-top: 12px; }
}

/* Phones: badge always sits under the title, so every row has the same rhythm */
@media (max-width: 599px) {
  .portfolio-head {
    flex-direction: column;
    align-items: flex-start;
  }

  .portfolio-badge { top: 0; }
}

@media (min-width: 800px) {
  .portfolio-item {
    grid-template-columns: 40px minmax(0, 1fr) 20px;
    column-gap: 16px;
    padding-block: 26px;
  }

  .portfolio-item::before { font-size: 18px; }
}


/* -------------------------------------------------------------------------
   26 Page: daily brief (daily-brief.html)
   A .page-head (date eyebrow + title), then one .brief-section per topic:
   the topic (h2) sits in the label column, its items in the body column.
   Header and footer are the shared ones (06, 19). Wrap the page in
   <main class="brief"> so the up/down colors below apply.
   ------------------------------------------------------------------------- */
.brief {
  --brief-up: #15803D;
  --brief-down: #B91C1C;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brief {
    --brief-up: #6DD49A;
    --brief-down: #F28B82;
  }
}

:root[data-theme="dark"] .brief {
  --brief-up: #6DD49A;
  --brief-down: #F28B82;
}

/* Date eyebrow ("Sample brief · date"): one line on phones, the date on its
   own line in the label column on desktop, lined up after the accent rule */
@media (min-width: 800px) {
  .brief-sep { display: none; }

  .brief-date {
    display: block;
    margin-top: 2px;
    padding-left: 32px;
  }
}

.brief-meta {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: 40rem;
  margin-top: 24px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
}

.brief-meta .icon {
  margin-top: 0.25em;
  color: var(--accent);
}

.brief-sections { padding-bottom: var(--space-section); }

.brief-section {
  border-top: 1px solid var(--line);
  padding-block: clamp(28px, 4vw, 44px);
}

.brief-section:last-child { border-bottom: 1px solid var(--line); }

.brief-section .split-body > * { max-width: 44rem; }

.brief-section-title {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.2vw, 26px);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.012em;
  color: var(--ink);
}

.brief-overview {
  display: grid;
  row-gap: 18px;
}

.brief-overview > li {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  column-gap: 12px;
  align-items: baseline;
}

.brief-num {
  font-family: var(--font-serif);
  font-size: 18px;
  line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--accent);
}

.brief-overview p,
.brief-list > li {
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}

.brief-list { row-gap: 14px; }

/* One-line takeaway under each topic */
.brief-summary {
  margin-top: 24px;
  padding-left: 18px;
  border-left: 2px solid var(--accent);
  font-family: var(--font-serif);
  font-size: 18.5px;
  font-style: italic;
  line-height: 1.5;
  color: var(--ink);
}

.brief-rate {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px 24px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--line);
}

.brief-rate-value {
  font-family: var(--font-serif);
  font-size: clamp(44px, 4.4vw, 58px);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: lining-nums;
  color: var(--ink);
}

.brief-rate-label {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--muted);
}

.brief-trend {
  padding: 4px 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-2);
}

.brief-subhead {
  margin: 28px 0 16px;
  font-family: var(--font-sans);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.brief-summary + .brief-subhead { margin-top: 44px; }

/* Stocks and crypto: name and note left, figures right */
.brief-rows > li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 24px;
  padding-block: 16px;
}

.brief-rows > li:first-child { padding-top: 0; }
.brief-rows > li + li { border-top: 1px solid var(--line); }

.brief-name {
  font-size: 15.5px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
}

.brief-note {
  margin-top: 4px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--muted);
}

.brief-figures { text-align: right; }

.brief-price {
  font-size: 16px;
  font-weight: 500;
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);
}

.brief-change {
  margin-top: 4px;
  font-size: 13.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--brief-up);
}

.brief-badge {
  display: inline-block;
  margin-top: 6px;
  padding: 2px 8px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.brief-badge--up {
  border-color: currentColor;
  color: var(--brief-up);
}

.brief-apps > li { padding-block: 18px; }
.brief-apps > li:first-child { padding-top: 0; }
.brief-apps > li:last-child { padding-bottom: 0; }
.brief-apps > li + li { border-top: 1px solid var(--line); }

.brief-app-name {
  font-family: var(--font-serif);
  font-size: clamp(19px, 1.9vw, 23px);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.012em;
  color: var(--ink);
}

.brief-app-desc {
  margin-top: 8px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
}

.brief-apps .brief-note { margin-top: 8px; }

/* Small category label above an idea's name */
.brief-tag {
  margin-bottom: 6px;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}

.split-body > .brief-subhead:first-child { margin-top: 0; }

.brief-rows + .brief-list { margin-top: 24px; }

.brief-change--down { color: var(--brief-down); }

/* Small source link after an item; opens the original story in a new tab */
.brief-source {
  font-size: 13.5px;
  font-weight: 500;
  white-space: nowrap;
  color: var(--muted);
}

.brief-source .icon {
  margin-left: 3px;
  vertical-align: 0;
  color: var(--accent);
  transition: transform 0.2s var(--ease);
}

.brief-source:hover { color: var(--accent); }
.brief-source:hover .icon { transform: translate(1px, -1px); }

/* Source list at the end of a topic */
.brief-sources {
  margin-top: 20px;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--muted);
}

.brief-sources a {
  font-weight: 500;
  color: var(--ink-2);
}

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

/* Sparklines are the brief's block glyphs (decorative, aria-hidden);
   each one is followed by a visually hidden description of its shape */
.brief-spark {
  margin-left: 8px;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  font-size: 15px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 1px;
  white-space: nowrap;
  color: var(--accent);
}

.brief-rate-value .brief-spark {
  margin-left: 16px;
  font-size: 24px;
  letter-spacing: 2px;
}

.brief-spark-line { margin-top: 6px; }
.brief-spark-line .brief-spark { margin-left: 0; }

/* Narrow phones: smaller sparklines leave room for the notes beside them */
@media (max-width: 400px) {
  .brief-spark {
    font-size: 13px;
    letter-spacing: 0;
  }
}


/* -------------------------------------------------------------------------
   27 Page: inspection app case studies (offline-team-inspection-app.html,
      paperless-quality-check-app.html, inspection-readiness-app.html)
   A .page-head with a context line and the app's facts, then one
   .case-section per topic: the topic (h2) sits in the label column, its
   content in the body column. All three pages share this markup:
   <div class="case-sections"><div class="container">
     <section class="case-section split" aria-labelledby="...">
       <div class="split-label"><h2 class="case-title" id="...">Topic</h2></div>
       <div class="split-body">...</div>
     </section>
   </div></div>
   Facts: <dl class="case-facts"><div><dt>Label</dt><dd>Value</dd></div></dl>
   Screens: <p class="case-note">, then
   <div class="case-gallery"><div class="case-shots">
     <figure class="case-shot case-shot--wide"><img ...><figcaption>...</figcaption></figure>
   </div></div>
   Shot kinds: --wide (landscape iPad, full row), --tall (portrait iPad,
   two per row), --aside (a lone portrait shot with its caption beside it).
   Add .case-shots--phone to the grid for iPhone shots (2 across, capped so
   each phone stays readable). Each img is wrapped in a link to its file.
   The grid sizes itself to its own width (container queries), so it works
   in the body column at every viewport from 320px up.
   ------------------------------------------------------------------------- */

/* Eyebrow ("iOS App · iPad"): one line on phones; on desktop the platform
   gets its own line in the label column, lined up after the accent rule */
@media (min-width: 800px) {
  .case-sep { display: none; }

  .case-platform {
    display: block;
    margin-top: 2px;
    padding-left: 32px;
  }
}

/* Long app names: balance the lines so "App" never sits alone */
.case-h1 { text-wrap: balance; }

.case-context {
  max-width: 40rem;
  margin-top: 16px;
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
}

.case-facts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: 32px;
  max-width: 46rem;
  margin-top: 32px;
  border-bottom: 1px solid var(--line);
}

.case-facts > div {
  min-width: 0;
  border-top: 1px solid var(--line);
  padding-block: 14px;
}

.case-facts dt {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.case-facts dd {
  margin-top: 4px;
  font-size: 15.5px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink);
}

@media (min-width: 600px) {
  .case-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.case-sections { padding-bottom: var(--space-section); }

.case-section {
  border-top: 1px solid var(--line);
  padding-block: clamp(28px, 4vw, 44px);
}

.case-section:last-child { border-bottom: 1px solid var(--line); }

.case-title {
  font-family: var(--font-serif);
  font-size: clamp(22px, 2.2vw, 26px);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.012em;
  color: var(--ink);
  text-wrap: balance;
}

.case-section .dash-list { max-width: 44rem; }

/* "Stack: ..." line under How it's built */
.case-stack {
  max-width: 44rem;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-2);
}

.case-stack-label {
  display: block;
  margin-bottom: 4px;
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* "Screens shown with sample data" note above the gallery */
.case-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  max-width: 40rem;
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
}

.case-note .icon {
  margin-top: 0.25em;
  color: var(--accent);
}

.case-note strong { color: var(--ink); }

.case-gallery {
  margin-top: 28px;
  container-type: inline-size;
}

.case-shots {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 40px 24px;
}

.case-shot { min-width: 0; }

/* The screens' drop shadows stop at the image's bottom edge, which would draw a
   faint hard line on the page. Fade the last 3% of each image (the device frames
   all end above 96.9% of the height, so only shadow is faded). */
.case-shot img {
  width: 100%;
  -webkit-mask-image: linear-gradient(to bottom, #000 97%, transparent);
  mask-image: linear-gradient(to bottom, #000 97%, transparent);
}

.case-shot figcaption {
  max-width: 40rem;
  margin-top: 12px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted);
}

.case-shot figcaption strong { color: var(--ink); }

@container (min-width: 520px) {
  .case-shots { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .case-shot--wide,
  .case-shot--aside { grid-column: 1 / -1; }

  .case-shot--aside {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 24px;
    align-items: center;
  }

  .case-shot--aside figcaption { margin-top: 0; }
}

/* iPhone shots: always two across, capped so each phone tops out near life size */
.case-shots--phone {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 32px 16px;
  max-width: 640px;
}

/* Each screen links to its full-size file */
.case-shot-link { display: block; cursor: zoom-in; }

/* By the numbers */
.case-table {
  width: 100%;
  max-width: 44rem;
  border-collapse: collapse;
  font-size: 15.5px;
  line-height: 1.5;
}

.case-table th,
.case-table td {
  padding: 14px 0;
  border-top: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.case-table thead th {
  padding-top: 0;
  padding-bottom: 10px;
  border-top: 0;
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

.case-table tbody th {
  width: 46%;
  padding-right: 24px;
  font-weight: 500;
  color: var(--ink-2);
}

.case-table td {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.case-table tbody tr:last-child > * { border-bottom: 1px solid var(--line); }

/* Other inspection apps: the home page's link rows, then a link back to the portfolio */
.case-related .build-list {
  max-width: 44rem;
  margin-top: 0;
}

.case-back { margin-top: 20px; }
