/* =================================================================
   Michael Stiso — Portfolio v2 (dashboard)
   Three pages laid out from "CV site.pptx": index.html (home),
   experiences.html and projects.html. Each page is a grid of panels
   that fills the viewport at 1100px and up, with long panels scrolling
   inside themselves. Below that the panels restack and the page scrolls.
   Independent of ../style.css — nothing here touches the current site.
   ================================================================= */

/* ---------------------------------------------------------------
   0. Tokens — shadcn names, this site's palette.
   The orange is the darkened #b4541c the palette critique recommended
   (4.53:1 on cream) and #d56421 on the dark panel (4.52:1).
   --------------------------------------------------------------- */
:root {
  --background:         #f7f4ee;
  --foreground:         #211d19;
  --card:               #fcfaf6;
  --muted:              #efe9df;
  --muted-foreground:   #6e675e;
  --primary:            #b4541c;
  --primary-soft:       rgba(180, 84, 28, .10);
  --border:             rgba(33, 29, 25, .14);
  --border-strong:      rgba(33, 29, 25, .32);

  --sidebar:            #211d19;
  --sidebar-foreground: #f2ede4;
  --sidebar-muted:      #a89f92;
  --sidebar-primary:    #d56421;
  --sidebar-border:     rgba(242, 237, 228, .16);

  --serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --sans:  'Archivo', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --gap: 20px;
  --pad: 22px;
  --menu-h: 52px;
}

/* ---------------------------------------------------------------
   1. Base
   --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: var(--primary); text-underline-offset: 2px; text-decoration-color: rgba(180, 84, 28, .4); }
a:hover { color: var(--foreground); }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
h1, h2, h3, h4 { margin: 0; font-weight: 500; }
p { margin: 0; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------------------------------------------------------------
   2. Dashboard frame and panels
   --------------------------------------------------------------- */
.dash {
  display: grid;
  gap: var(--gap);
  padding: var(--gap);
  max-width: 1600px;
  margin: 0 auto;
}

.panel {
  background: var(--card);
  border: 1px solid var(--border);
  padding: var(--pad);
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.panel-label {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 14px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.panel-label .aside {
  color: var(--muted-foreground);
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: none;
  font-size: 12px;
}
/* A panel whose body scrolls on its own when the dashboard is pinned
   to the viewport. */
.panel-scroll { overflow: auto; overscroll-behavior: contain; }

.panel.dark {
  background: var(--sidebar);
  border-color: var(--sidebar);
  color: var(--sidebar-foreground);
}
.panel.dark .panel-label { color: var(--sidebar-primary); }
.panel.dark a { color: var(--sidebar-foreground); text-decoration-color: var(--sidebar-border); }
.panel.dark a:hover { color: var(--sidebar-primary); }

/* ---------- Menu bar ---------- */
.menu {
  grid-area: menu;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 var(--pad) 0 8px;
  min-height: var(--menu-h);
}
.menu-links { display: flex; align-items: stretch; align-self: stretch; }
.menu-links a {
  display: flex;
  align-items: center;
  padding: 0 14px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 500;
  color: var(--muted-foreground);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
}
.menu-links a:hover { color: var(--foreground); }
.menu-links a[aria-current="page"] {
  color: var(--foreground);
  border-bottom-color: var(--primary);
}
.menu-meta {
  display: flex;
  gap: 18px;
  font-family: var(--sans);
  font-size: 13px;
  white-space: nowrap;
}
.menu-meta a { text-decoration: none; }
.menu-meta a:hover { text-decoration: underline; }

/* ---------- Name block (work history, projects) ---------- */
.brand {
  grid-area: brand;
  flex-direction: row;
  align-items: center;
  gap: 12px;
  padding: 0 var(--pad) 0 10px;
  min-height: var(--menu-h);
  text-decoration: none;
  color: var(--foreground);
}
.brand:hover { color: var(--foreground); border-color: var(--border-strong); }
.brand-mark {
  flex: none;
  width: 32px; height: 32px;
  display: grid; place-items: center;
  background: var(--sidebar);
  color: var(--sidebar-foreground);
  font-family: var(--serif);
  font-size: 15px;
}
.brand-name { font-size: 17px; line-height: 1.15; }
.brand-title {
  display: block;
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}

/* ---------------------------------------------------------------
   3. Home
   Slide 1: portrait, blurb and contact down the left; menu, intro and
   summary on the right. The portrait's bottom lines up with the
   intro's, and the blurb's top with the summary's, as on the slide.
   --------------------------------------------------------------- */
.dash-home {
  grid-template-columns: minmax(250px, 22fr) 72fr;
  grid-template-rows: auto 1fr 1fr .62fr;
  grid-template-areas:
    "img     menu"
    "img     intro"
    "blurb   summary"
    "contact summary";
}
.home-img {
  grid-area: img;
  padding: 0;
  overflow: hidden;
}
.portrait-placeholder {
  flex: 1;
  min-height: 180px;
  display: grid;
  place-items: center;
  background:
    repeating-linear-gradient(135deg, transparent 0 14px, rgba(242, 237, 228, .035) 14px 15px),
    var(--sidebar);
  color: var(--sidebar-foreground);
  font-family: var(--serif);
  font-size: 64px;
  font-weight: 300;
  letter-spacing: .02em;
}
.portrait { flex: 1; width: 100%; height: 100%; object-fit: cover; }

.home-blurb { grid-area: blurb; overflow: auto; }
.home-blurb h1 { font-size: 26px; line-height: 1.15; }
.home-blurb .role {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--primary);
  margin: 8px 0 14px;
}
.home-blurb p { color: var(--muted-foreground); font-size: 16px; line-height: 1.5; }

.home-contact { grid-area: contact; justify-content: space-between; }
.contact-list { list-style: none; margin: 0; padding: 0; font-family: var(--sans); font-size: 14px; }
.contact-list li + li { margin-top: 6px; }
.contact-list .loc { color: var(--sidebar-muted); }

.home-intro { grid-area: intro; justify-content: space-between; overflow: auto; }
.home-intro .lede {
  font-size: clamp(20px, 1.75vw, 26px);
  line-height: 1.32;
  max-width: 54ch;
  text-wrap: pretty;
}
.home-intro .lede em { font-style: italic; color: var(--primary); }
.intro-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin-top: 18px;
  font-family: var(--sans);
  font-size: 14px;
  font-weight: 500;
}
.intro-links a { text-decoration: none; }
.intro-links a:hover { text-decoration: underline; }

.home-summary { grid-area: summary; }

/* Summary tabs: "Approach" (the four summary cells) and "AI & UX". */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; }
.tab {
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: 0 2px 10px;
  margin-right: 18px;
  cursor: pointer;
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.tab:hover { color: var(--foreground); }
.tab[aria-selected="true"] { color: var(--primary); border-bottom-color: var(--primary); }
.tabpanel { flex: 1; min-height: 0; overflow: auto; }
.tabpanel[hidden] { display: none; }
.tabpanel-intro { color: var(--muted-foreground); font-size: 15px; max-width: 80ch; margin-bottom: 16px; }

.cells {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
}
.cells.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cell { background: var(--card); padding: 18px 20px; }
.cell .num {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  color: var(--primary);
  letter-spacing: .08em;
  display: block;
  margin-bottom: 6px;
}
.cell h3 { font-size: 19px; line-height: 1.2; margin-bottom: 6px; }
.cell p { font-size: 15px; line-height: 1.5; color: var(--muted-foreground); }

/* ---------------------------------------------------------------
   4. Work history
   Slide 2: name and menu across the top (at a different split from the
   panels below), the horizontal graphic on the left and the scrolling
   description on the right.
   --------------------------------------------------------------- */
.dash-wh {
  grid-template-columns: 31fr 29fr 36fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "brand menu  menu"
    "graph graph text";
}
.wh-graph { grid-area: graph; }
.wh-text { grid-area: text; }

/* ---------- The Gantt ----------
   Years run left to right across the track, 1998 to 2026. Every
   left/width is a percentage of that 28-year span, set inline:
   left = (start − 1998) / 28, width = (end − start) / 28. */
.gantt {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(150px, 30%) 1fr;
  grid-template-rows: auto 1fr auto;
  column-gap: 16px;
}
.g-head, .g-track-area, .g-axis { grid-column: 2; position: relative; }
.g-rows { grid-column: 1 / -1; grid-row: 2; position: relative; z-index: 1; display: flex; flex-direction: column; }

/* Era header: one cell per era, same percentages as the bands. */
.g-head { grid-row: 1; height: 64px; }
.g-era-label {
  position: absolute;
  top: 0; bottom: 0;
  padding: 0 6px 8px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  border-left: 1px solid var(--border-strong);
  background: none;
  border-top: 0; border-right: 0; border-bottom: 0;
  text-align: left;
  cursor: pointer;
  font-family: var(--sans);
  color: var(--foreground);
  text-decoration: none;
}
.g-era-label b { font-size: 12px; font-weight: 600; line-height: 1.2; }
.g-era-label span { font-size: 11px; color: var(--muted-foreground); white-space: nowrap; }
.g-era-label:hover b { color: var(--primary); }

/* Era bands sit behind the rows, in the track column only: they share
   grid row 2 with .g-rows, which is drawn on top. */
.g-bands { grid-column: 2; grid-row: 2; position: relative; pointer-events: none; }
.g-band { position: absolute; top: 0; bottom: 0; border-left: 1px solid var(--border-strong); }
.g-band.alt { background: var(--muted); }
.g-band.side {
  border-left: 1px dashed var(--border-strong);
  border-right: 1px dashed var(--border-strong);
  background: repeating-linear-gradient(135deg, transparent 0 6px, rgba(180, 84, 28, .07) 6px 7px);
}
.g-band-note {
  position: absolute;
  bottom: 6px; left: 5px; right: 2px;
  font-family: var(--sans);
  font-size: 10px;
  line-height: 1.2;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--primary);
}

.g-row {
  flex: 1;
  min-height: 46px;
  display: grid;
  grid-template-columns: minmax(150px, 30%) 1fr;
  column-gap: 16px;
  align-items: center;
  position: relative;
  padding: 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--border);
  text-align: left;
  cursor: pointer;
  color: var(--foreground);
  text-decoration: none;
}
.g-row:last-child { border-bottom: 1px solid var(--border); }
.g-label { padding: 6px 0; min-width: 0; }
.g-emp { display: block; font-family: var(--sans); font-size: 14px; font-weight: 600; line-height: 1.25; }
.g-role { display: block; font-size: 14px; line-height: 1.3; color: var(--muted-foreground); }
.g-track { position: relative; height: 100%; min-height: 20px; }
.g-bar {
  position: absolute;
  top: 50%;
  height: 12px;
  transform: translateY(-50%);
  background: var(--primary);
}
.g-bar.ongoing { background: linear-gradient(90deg, var(--primary) 70%, rgba(180, 84, 28, .35)); }
.g-bar.dot { width: 10px; height: 10px; border-radius: 50%; margin-left: -5px; }
.g-dates {
  position: absolute;
  top: calc(50% + 9px);
  font-family: var(--sans);
  font-size: 11px;
  color: var(--muted-foreground);
  white-space: nowrap;
}
.g-dates.end { transform: translateX(-100%); }

.g-row:hover .g-emp { color: var(--primary); }
.g-row[aria-current="true"] { background: var(--primary-soft); }
.g-row[aria-current="true"] .g-emp { color: var(--primary); }
.g-row[aria-current="true"] .g-bar { background: var(--foreground); }
.g-row[aria-current="true"] .g-bar.ongoing { background: linear-gradient(90deg, var(--foreground) 70%, rgba(33, 29, 25, .35)); }

.g-axis { grid-row: 3; height: 26px; }
.g-tick {
  position: absolute;
  top: 0;
  padding-top: 6px;
  transform: translateX(-50%);
  font-family: var(--sans);
  font-size: 11px;
  color: var(--muted-foreground);
}
.g-tick::before { content: ""; position: absolute; top: 0; left: 50%; height: 4px; border-left: 1px solid var(--border-strong); }
.g-tick.first { transform: none; }
.g-tick.first::before { left: 0; }
.g-tick.last { transform: translateX(-100%); }
.g-tick.last::before { left: auto; right: 0; }

.g-foot {
  margin-top: 14px;
  font-family: var(--sans);
  font-size: 12px;
  color: var(--muted-foreground);
}

/* ---------- Description column ---------- */
.wh-text .era + .era { margin-top: 34px; }
.era-head { padding-bottom: 12px; border-bottom: 1px solid var(--border-strong); margin-bottom: 4px; }
.era-head h2 { font-size: 24px; line-height: 1.15; }
.era-span {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: .06em;
  color: var(--primary);
  display: block;
  margin: 2px 0 8px;
}
.era-head p { color: var(--muted-foreground); font-size: 16px; }
.era-head .side-note {
  margin-top: 10px;
  padding: 8px 10px;
  border-left: 2px solid var(--primary);
  background: var(--primary-soft);
  font-size: 15px;
  color: var(--foreground);
}
.job {
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
  scroll-margin-top: 8px;
}
.job:last-child { border-bottom: 0; }
.job h3 { font-family: var(--sans); font-size: 16px; font-weight: 600; }
.job-meta {
  font-family: var(--sans);
  font-size: 12.5px;
  color: var(--muted-foreground);
  margin: 2px 0 8px;
}
.job p { font-size: 16px; line-height: 1.5; }
.job .cs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin-top: 8px;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
}
.job .cs a { text-decoration: none; }
.job .cs a:hover { text-decoration: underline; }
.job.is-active h3 { color: var(--primary); }
.extras { margin-top: 34px; display: grid; gap: 18px; }
.extras h2 {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 6px;
}
.extras ul { margin: 0; padding-left: 18px; }
.extras li { font-size: 15px; }

/* ---------------------------------------------------------------
   5. Projects
   Slide 3: project tiles down the left, the selected project's full
   description on the right.
   --------------------------------------------------------------- */
.dash-projects {
  grid-template-columns: minmax(250px, 22fr) 72fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "brand menu"
    "list  detail";
}
.proj-nav { grid-area: list; min-width: 0; min-height: 0; display: flex; }
.proj-list {
  flex: 1;
  min-width: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  overflow: auto;
  overscroll-behavior: contain;
  min-height: 0;
}
.proj-tile {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--foreground);
  text-decoration: none;
}
.proj-tile:hover { border-color: var(--border-strong); color: var(--foreground); }
.proj-tile[aria-current="true"] { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.proj-thumb {
  aspect-ratio: 16 / 7;
  display: grid;
  place-items: center;
  background: repeating-linear-gradient(135deg, var(--muted) 0 10px, #e9e2d6 10px 11px);
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.proj-tile-text { display: block; padding: 12px 14px 14px; }
.proj-tile-meta {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--primary);
  display: block;
}
.proj-tile-title { display: block; font-size: 18px; line-height: 1.2; margin-top: 3px; }

.proj-detail { grid-area: detail; }
.proj { max-width: 880px; }
.proj + .proj { margin-top: 60px; }
.js .proj + .proj { margin-top: 0; }
.js .proj:not(.is-shown) { display: none; }
.proj-meta {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--primary);
}
.proj-title { font-size: clamp(28px, 3vw, 40px); line-height: 1.1; margin: 6px 0 8px; }
.proj-subtitle { font-size: 19px; color: var(--muted-foreground); max-width: 60ch; }

/* Project at a glance: the Deliverable / Topic / Goal / Strategy
   summary from the current site's project cards, as stat tiles. */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  margin: 22px 0;
}
.fact { background: var(--background); padding: 12px 14px; }
.fact dt {
  font-family: var(--sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-bottom: 4px;
}
.fact dd { margin: 0; font-size: 15px; line-height: 1.4; }
.proj-hero {
  aspect-ratio: 16 / 4.5;
  display: grid;
  place-items: center;
  margin: 22px 0 8px;
  padding: 0 16px;
  text-align: center;
  background: repeating-linear-gradient(135deg, var(--muted) 0 10px, #e9e2d6 10px 11px);
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.proj-body section { margin-top: 26px; }
.proj-body h2 {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--primary);
  padding-top: 12px;
  border-top: 1px solid var(--border);
  margin-bottom: 8px;
}
.proj-body h3 { font-size: 19px; margin: 14px 0 6px; }
.proj-body p { font-size: 17px; line-height: 1.6; }
.proj-body p + p { margin-top: 12px; }
.proj-body ul, .proj-body ol { padding-left: 20px; font-size: 17px; line-height: 1.55; }
.proj-body li + li { margin-top: 6px; }
.proj-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 28px; }
.proj-tags span {
  font-family: var(--sans);
  font-size: 12px;
  padding: 3px 9px;
  border: 1px solid var(--border-strong);
  color: var(--muted-foreground);
}
.proj-worklink {
  margin-top: 18px;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 500;
}
.proj-worklink a { text-decoration: none; }
.proj-worklink a:hover { text-decoration: underline; }

/* ---------------------------------------------------------------
   6. Pinned to the viewport (1100px and up)
   The whole dashboard is one screen; long panels scroll inside.
   --------------------------------------------------------------- */
@media (min-width: 1100px) and (min-height: 640px) {
  .dash { height: 100vh; height: 100dvh; }
  .home-summary, .wh-text, .proj-detail { overflow: auto; overscroll-behavior: contain; }
  .wh-text, .proj-detail { padding-right: calc(var(--pad) + 6px); }
}

/* ---------------------------------------------------------------
   7. Tablet (below 1100px): panels restack, page scrolls.
   --------------------------------------------------------------- */
@media (max-width: 1099.98px), (max-height: 639.98px) {
  .dash-home {
    grid-template-columns: minmax(200px, 1fr) 2fr;
    grid-template-rows: auto;
    grid-template-areas:
      "menu    menu"
      "img     blurb"
      "img     contact"
      "intro   intro"
      "summary summary";
  }
  .home-img { min-height: 260px; }
  .dash-wh {
    grid-template-columns: auto 1fr;
    grid-template-areas: "brand menu" "graph graph" "text text";
  }
  .dash-projects {
    grid-template-columns: auto 1fr;
    grid-template-areas: "brand menu" "list list" "detail detail";
  }
  .brand { min-height: 0; padding: 10px var(--pad) 10px 10px; }
  .menu-meta a[href^="mailto:"] { display: none; }
  .wh-graph { min-height: 560px; }

  /* The project tiles become a sideways strip above the detail. */
  .proj-list {
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    gap: 12px;
    padding-bottom: 6px;
  }
  .proj-list li { flex: 0 0 220px; scroll-snap-align: start; }
  .proj-tile { height: 100%; }
  .proj-thumb { aspect-ratio: 16 / 7; }
}

/* ---------------------------------------------------------------
   8. Phone (below 700px)
   --------------------------------------------------------------- */
@media (max-width: 699.98px) {
  :root { --gap: 12px; --pad: 16px; }
  .dash-home {
    grid-template-columns: 1fr;
    grid-template-areas: "menu" "img" "blurb" "intro" "summary" "contact";
  }
  .home-img { min-height: 0; }
  .portrait-placeholder { min-height: 150px; font-size: 48px; }

  .menu { flex-wrap: wrap; padding: 0 var(--pad) 0 4px; }
  .menu-links a { padding: 0 10px; font-size: 14px; min-height: 48px; }
  .menu-meta { display: none; }

  .cells, .cells.three { grid-template-columns: 1fr; }
  .dash-wh, .dash-projects { grid-template-columns: 1fr; }
  .dash-wh { grid-template-areas: "brand" "menu" "graph" "text"; }
  .dash-projects { grid-template-areas: "brand" "menu" "list" "detail"; }

  /* Gantt: the label sits above its bar instead of beside it. */
  .wh-graph { min-height: 0; }
  .gantt { grid-template-columns: 0 1fr; column-gap: 0; }
  .g-row { grid-template-columns: 1fr; min-height: 0; padding: 8px 0 4px; }
  .g-label { padding: 0 0 2px; position: relative; z-index: 1; }
  .g-emp, .g-role { display: inline; font-size: 13.5px; }
  .g-role::before { content: " · "; }
  .g-track { height: 34px; }
  /* Era names are wider than their bands here, so they alternate
     between two lines and the last one hangs from the right edge. The
     axis carries the years. */
  .g-head { height: 44px; }
  .g-era-label { width: auto !important; padding: 0 4px; white-space: nowrap; }
  .g-era-label:nth-child(odd) { top: 0; bottom: 20px; justify-content: flex-start; }
  .g-era-label:nth-child(even) { top: 20px; bottom: 0; justify-content: flex-end; padding-bottom: 5px; }
  .g-era-label:last-child { left: auto !important; right: 0; border-left: 0; border-right: 1px solid var(--border-strong); text-align: right; }
  .g-era-label b { font-size: 11px; }
  .g-era-label span { display: none; }
  .g-band-note { font-size: 9px; }
  .g-tick { font-size: 10px; }
  .g-tick.mid-optional { display: none; }

  .proj-list li { flex-basis: 180px; }
  .proj-subtitle { font-size: 17px; }
  .proj-body p, .proj-body ul, .proj-body ol { font-size: 16px; }
}

/* ---------------------------------------------------------------
   9. Home — golden spiral (index.html)
   One golden rectangle, width : height = φ : 1 (φ ≈ 1.618), cut into
   squares that each shrink by 1/φ and turn clockwise. Every left/top
   is a percentage of the rectangle's width/height:
     sq1  left square        0      0       61.803 × 100      name, intro, summary
     sq2  top right          61.803 0       38.197 × 61.803   portrait
     (sq3 contact, sq4 location, sq5–eye colour only)
     sq3  bottom right       76.393 61.803  23.607 × 38.197
     sq4  bottom             61.803 76.393  14.590 × 23.607
     sq5  left               61.803 61.803   9.017 × 14.590
     sq6  top                70.820 61.803   5.573 ×  9.017
     sq7  right              72.949 70.820   3.444 ×  5.573
     eye  what's left        70.820 70.820   2.129 ×  5.573
   Below 1200px the squares get too small for their text, so they
   stack in spiral order instead.
   --------------------------------------------------------------- */
.spiral-page { min-height: 100vh; }
.spiral-nav {
  max-width: 1440px;
  margin: 0 auto;
  padding: 10px 24px 0;
  display: flex;
}
.spiral-nav .menu-links a { min-height: 44px; padding: 0 12px; }
.spiral-nav .menu-links a:first-child { padding-left: 0; }

.spiral {
  position: relative;
  max-width: 1440px;
  margin: 12px auto 40px;
  padding: 0 24px;
}

.eyebrow-s {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--primary);
  margin: 0 0 12px;
}

.sq { border: 1px solid var(--border-strong); min-width: 0; }

/* 1 */
.sq1 { padding: clamp(24px, 3.4vw, 48px); display: flex; flex-direction: column; justify-content: space-between; gap: 28px; }
.sq1 h1 { font-size: clamp(36px, 3.9vw, 58px); line-height: 1.02; letter-spacing: -.01em; }
.sq1 .lede { font-size: clamp(18px, 1.55vw, 23px); line-height: 1.38; margin-top: 18px; max-width: 40em; text-wrap: pretty; }
.sq1 .lede em { color: var(--primary); }
.sq1-cells {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--border-strong);
}
.sq1-cells .cell { background: none; padding: 16px 22px 0 0; }
.sq1-cells .cell:nth-child(even) { padding: 16px 0 0 22px; border-left: 1px solid var(--border); }
.sq1-cells .cell:nth-child(n+3) { border-top: 1px solid var(--border); margin-top: 16px; }
.sq1-cells h2 { font-size: 18px; line-height: 1.2; margin-bottom: 5px; }
.sq1-cells p { font-size: 14.5px; line-height: 1.5; color: var(--muted-foreground); }

/* 2 · portrait */
.sq-portrait { display: flex; background: var(--sidebar); border-color: var(--sidebar); }
.sq-portrait .portrait-placeholder { min-height: 0; font-size: clamp(48px, 6vw, 96px); }

/* 3 · contact */
.sq-contact {
  padding: clamp(16px, 1.8vw, 28px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 6px;
  font-family: var(--sans);
  font-size: 15px;
}
.sq-contact .eyebrow-s { margin: 0 0 auto; }
.sq-contact a { text-decoration: none; font-weight: 500; }
.sq-contact a:hover { text-decoration: underline; }

/* 4 · where, then colour to the eye */
.sq-where {
  display: flex;
  align-items: flex-end;
  padding: 12px 14px;
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.3;
  color: var(--muted-foreground);
}
.sq5 { background: var(--muted); }
.sq6 { background: var(--primary); border-color: var(--primary); }
.sq7 { background: var(--foreground); border-color: var(--foreground); }
.sq-eye { background: var(--primary-soft); }

/* The spiral proper: only where the squares are big enough. */
@media (min-width: 1200px) {
  .spiral::before { content: ""; display: block; padding-top: 61.8034%; }
  .spiral > .sq {
    position: absolute;
    margin: -.5px;           /* neighbouring borders overlap into one line */
  }
  /* Everything is placed inside the 24px side padding. */
  .spiral > .sq { --w: calc(100% - 48px); }
  .sq1   { left: 24px;                              top: 0;        width: calc(var(--w) * .618034); height: 100%; }
  .sq2   { left: calc(24px + var(--w) * .618034);  top: 0;        width: calc(var(--w) * .381966); height: 61.8034%; }
  .sq3   { left: calc(24px + var(--w) * .763932);  top: 61.8034%; width: calc(var(--w) * .236068); height: 38.1966%; }
  .sq4   { left: calc(24px + var(--w) * .618034);  top: 76.3932%; width: calc(var(--w) * .145898); height: 23.6068%; }
  .sq5   { left: calc(24px + var(--w) * .618034);  top: 61.8034%; width: calc(var(--w) * .090170); height: 14.5898%; }
  .sq6   { left: calc(24px + var(--w) * .708204);  top: 61.8034%; width: calc(var(--w) * .055728); height:  9.0170%; }
  .sq7   { left: calc(24px + var(--w) * .729490);  top: 70.8204%; width: calc(var(--w) * .034442); height:  5.5728%; }
  .sq-eye{ left: calc(24px + var(--w) * .708204);  top: 70.8204%; width: calc(var(--w) * .021286); height:  5.5728%; }
}

/* Stacked, in spiral order. */
@media (max-width: 1199.98px) {
  .spiral { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
  .sq1 { grid-column: 1 / -1; }
  .sq-portrait { aspect-ratio: 1; }
  .sq5, .sq6, .sq7, .sq-eye { display: none; }
}
@media (max-width: 699.98px) {
  .spiral-nav { padding: 6px 12px 0; }
  .spiral { padding: 0 12px; gap: 10px; margin-top: 8px; }
  .sq1-cells { grid-template-columns: 1fr; }
  .sq1-cells .cell, .sq1-cells .cell:nth-child(even) { padding: 14px 0 0; border-left: 0; }
  .sq1-cells .cell + .cell { border-top: 1px solid var(--border); margin-top: 14px; }
  .spiral { grid-template-columns: 1fr 1fr; }
  .sq-portrait { grid-column: 1; grid-row: span 2; aspect-ratio: auto; min-height: 150px; }
}

/* ---------------------------------------------------------------
   10. Home — modular scale + fluid ratio grid (index.html)
   One scale sets both type and space. It runs fluidly from a 16px
   base with ratio 1.2 (minor third) at a 360px viewport to a 19px
   base with ratio 1.333 (perfect fourth) at 1440px, so headings
   spread further apart as the screen grows:
     step n = base × ratio^n, interpolated between the two ends.
   The grid uses the same ratio: columns split 4 : 3, and the page's
   width is capped at 1440px.
   The golden-spiral home (section 9) is kept as index-spiral.html.
   --------------------------------------------------------------- */
.ms-page {
  --step-m2: .7rem;
  --step-m1: clamp(0.8333rem, 0.8142rem + 0.0852vw, 0.8908rem);
  --step-0:  clamp(1.0000rem, 0.9375rem + 0.2778vw, 1.1875rem);
  --step-1:  clamp(1.2000rem, 1.0724rem + 0.5673vw, 1.5829rem);
  --step-2:  clamp(1.4400rem, 1.2166rem + 0.9927vw, 2.1101rem);
  --step-3:  clamp(1.7280rem, 1.3664rem + 1.6070vw, 2.8127rem);
  --step-4:  clamp(2.0736rem, 1.5150rem + 2.4826vw, 3.7493rem);
  --step-5:  clamp(2.4883rem, 1.6518rem + 3.7178vw, 4.9979rem);
  --ratio-a: 4fr;   /* the larger side of 4 : 3 */
  --ratio-b: 3fr;
  font-size: var(--step-0);
}
.ms-wrap {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--step-2) var(--step-5);
}

.ms-nav { padding-top: var(--step-m1); }
.ms-nav .menu-links a { min-height: 44px; padding: 0 var(--step-m1); font-size: var(--step-m1); }
.ms-nav .menu-links a:first-child { padding-left: 0; }

.ms-eyebrow {
  margin: 0 0 var(--step-0);
  font-family: var(--sans);
  font-size: var(--step-m2);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--primary);
}

/* Hero: text and portrait split 4 : 3. */
.ms-hero {
  display: grid;
  grid-template-columns: var(--ratio-a) var(--ratio-b);
  gap: var(--step-4);
  align-items: end;
  padding: var(--step-5) 0 var(--step-4);
  border-bottom: 1px solid var(--border-strong);
}
.ms-name {
  font-size: var(--step-5);
  line-height: 1.02;
  letter-spacing: -.015em;
  font-weight: 400;
}
.ms-lede {
  margin-top: var(--step-2);
  font-size: var(--step-1);
  line-height: 1.4;
  max-width: 34em;
  text-wrap: pretty;
}
.ms-lede em { color: var(--primary); }
/* The portrait is square. Its height follows the text beside it (the
   row stretches to the text, and the width follows from 1 : 1), so the
   text never has to leave empty space above or below itself. */
.ms-portrait {
  align-self: stretch;
  justify-self: end;
  aspect-ratio: 1;
  max-width: 100%;
  min-height: 0;
  position: relative;
}
/* Taken out of flow so the photo's own size can't make the row taller. */
.ms-portrait img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }

/* Summary: four equal columns, then 2 × 2, then one. */
.ms-summary {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: var(--step-2);
  row-gap: var(--step-3);
  padding: var(--step-4) 0;
  border-bottom: 1px solid var(--border-strong);
}
.ms-cell h2 { font-size: var(--step-1); line-height: 1.2; margin-bottom: var(--step-m1); }
.ms-cell p { font-size: var(--step-0); line-height: 1.5; color: var(--muted-foreground); }

/* Footer: the contact line, on every page on this scale. */
/* Sticky footer, no script: the wrap is at least as tall as the window
   and a column, so on a short page the footer's auto top margin takes
   up the slack and it sits at the bottom of the window. On a page that
   scrolls there is no slack, and the content above keeps a fixed gap
   (the margin on the last block before the footer). */
.ms-wrap:has(.ms-footer) {
  padding-bottom: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
.ms-wrap:has(.ms-footer) > :nth-last-child(2) { margin-bottom: var(--step-4); }
/* The footer's rule replaces the summary's, so there is only one line. */
.ms-summary:has(+ .ms-footer) { border-bottom: 0; padding-bottom: 0; }
.ms-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--step-m1) var(--step-2);
  margin-top: auto;
  padding: var(--step-1) 0 var(--step-2);
  border-top: 1px solid var(--border-strong);
}
.ms-footer-label {
  margin: 0;
  font-family: var(--sans);
  font-size: var(--step-m2);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--primary);
}
.ms-contact-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--step-m1) var(--step-2);
  font-family: var(--sans);
  font-size: var(--step-m1);
}
.ms-contact-links a { text-decoration: none; font-weight: 500; }
.ms-contact-links a:hover { text-decoration: underline; }
.ms-contact-links span { color: var(--muted-foreground); }

@media (max-width: 1099.98px) {
  .ms-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 699.98px) {
  .ms-hero { grid-template-columns: 1fr; padding-top: var(--step-3); }
  .ms-portrait { order: -1; align-self: start; justify-self: start; width: 60%; }
  .ms-portrait img { position: static; }
  .ms-summary { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------
   11. Work history — modular scale + ratio grid (experiences.html)
   Uses section 10's scale and 4 : 3 split. One full-width graphic
   of four eras, newest first: each era is a row with its prose on
   the larger side, the spine in the middle and its employers on the
   smaller side. Row height is set by the content, not by duration;
   the dates carry the time scale. Each employer is a button that
   opens a tooltip with the job's details (hover, focus or tap).
   The dashboard page is kept as work-history-dashboard.html.
   --------------------------------------------------------------- */
.mw-head {
  padding: var(--step-5) 0 var(--step-3);
  border-bottom: 1px solid var(--border-strong);
}
/* The name sits in the top right corner, level with the menu. */
.ms-nav:has(.mw-owner) { display: flex; justify-content: space-between; align-items: center; gap: var(--step-0); }
.mw-owner {
  color: var(--foreground);
  font-family: var(--serif);
  font-size: var(--step-0);
  text-decoration: none;
  white-space: nowrap;
}
.mw-owner:hover { color: var(--primary); }

.mw-chart { padding-bottom: var(--step-3); }
.mw-era {
  display: grid;
  grid-template-columns: var(--ratio-a) var(--step-3) var(--ratio-b);
  column-gap: var(--step-2);
}
.mw-era-text, .mw-jobs { padding: var(--step-3) 0; min-width: 0; }
.mw-era + .mw-era .mw-era-text,
.mw-era + .mw-era .mw-jobs { border-top: 1px solid var(--border); }

.mw-era-name { font-size: var(--step-2); line-height: 1.1; font-weight: 400; }
.mw-era-span {
  margin: var(--step-m2) 0 var(--step-0);
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--primary);
}
.mw-era-note {
  font-size: var(--step-0);
  line-height: 1.5;
  max-width: 30em;
  text-wrap: pretty;
}
/* Enterprise UX, the side journey inside Applied research, set in its
   own column beside the era's text, level with its top. One rounded outline, drawn
   by v2.js as an SVG path, joins it to its employer, Oracle, across the
   spine, as on the v1 home page. Until the script has drawn it (and on
   phones, where the two no longer sit side by side) each box has its
   own border instead. */
.mw-era { position: relative; }
.mw-era-text.with-aside {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 12em;
  grid-auto-rows: min-content;
  column-gap: var(--step-2);
  align-content: start;
}
.mw-era-text.with-aside > * { grid-column: 1; }
.mw-era-text.with-aside > .mw-aside { grid-column: 2; grid-row: 1 / span 3; align-self: start; }
.mw-aside {
  padding: var(--step-m1) var(--step-0) var(--step-0);
  border: 1.5px solid var(--primary);
  font-size: var(--step-0);
}
.mw-aside-name { font-size: var(--step-1); line-height: 1.2; font-weight: 400; }
.mw-aside .mw-era-span { margin: var(--step-m2) 0 var(--step-m1); }
.mw-aside-note { color: var(--muted-foreground); line-height: 1.45; text-wrap: pretty; }
.mw-enclosure {
  display: none;
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  overflow: visible;
  pointer-events: none;
}
.mw-enclosure path { fill: none; stroke: var(--primary); stroke-width: 1.5; }
.mw-era.has-enclosure .mw-enclosure { display: block; }
.mw-era.has-enclosure .mw-aside,
.mw-era.has-enclosure .mw-job.aside { border-color: transparent; }

/* The spine: one line through every era, a square marker level with
   each era's name, and an arrowhead at the top pointing to now. */
.mw-spine { position: relative; }
.mw-spine::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  width: 3px;
  margin-left: -1.5px;
  background: var(--foreground);
}
.mw-spine::after {
  content: '';
  position: absolute;
  /* level with the middle of the era's name */
  top: calc(var(--step-3) + var(--step-2) * .55 - 6.5px);
  left: 50%;
  width: 13px; height: 13px;
  margin-left: -6.5px;
  background: var(--primary);
}
.mw-era:first-child .mw-spine::before { top: calc(var(--step-m1) + 10px); }
.mw-era.last .mw-spine::before { bottom: var(--step-3); }
.mw-arrow {
  position: absolute;
  top: var(--step-m1); left: 50%;
  margin-left: -8px;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-bottom: 13px solid var(--foreground);
}

/* Employers */
.mw-jobs { list-style: none; margin: 0; }
.mw-job { position: relative; }
.mw-job + .mw-job { border-top: 1px solid var(--border); }
.mw-job.aside {
  margin: var(--step-m2) 0;
  padding: 0 var(--step-m1);
  border: 1.5px solid var(--primary);
}
.mw-job.aside + .mw-job { border-top: 0; }
.mw-job.aside .mw-item { padding: var(--step-m1) 0; }
.mw-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--step-0);
  width: 100%;
  padding: var(--step-m1) 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.mw-job:first-child .mw-item { padding-top: 0; }
.mw-emp { font-family: var(--serif); font-size: var(--step-1); line-height: 1.2; }
.mw-meta {
  grid-column: 1;
  font-family: var(--sans);
  font-size: var(--step-m1);
  color: var(--muted-foreground);
}
.mw-dates { color: var(--foreground); font-weight: 600; margin-right: .3em; }
/* A small squared "i" says the row opens details. */
.mw-item::after {
  content: 'i';
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  width: 1.5em; height: 1.5em;
  line-height: 1.4em;
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-size: var(--step-m1);
  border: 1px solid var(--border-strong);
  color: var(--muted-foreground);
}
.mw-item:hover .mw-emp, .mw-item[aria-expanded="true"] .mw-emp { color: var(--primary); }
.mw-item:hover::after, .mw-item[aria-expanded="true"]::after {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.mw-item:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.mw-tip {
  display: none;
  position: absolute;
  z-index: 5;
  top: calc(100% - var(--step-m2));
  left: 0; right: 0;
  padding: var(--step-0);
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-top: 3px solid var(--primary);
  font-size: var(--step-0);
  line-height: 1.5;
}
.mw-job:hover .mw-tip,
.mw-item[aria-expanded="true"] + .mw-tip,
.mw-item:focus-visible + .mw-tip,
.mw-tip:focus-within { display: block; }
.mw-tip-meta {
  margin-bottom: var(--step-m2);
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 600;
}
.mw-tip-cs { display: flex; flex-wrap: wrap; gap: var(--step-m2) var(--step-0); margin-top: var(--step-m1); font-family: var(--sans); font-size: var(--step-m1); }
.mw-tip-cs a { color: var(--primary); font-weight: 600; text-decoration: none; }
.mw-tip-cs a:hover { text-decoration: underline; }

/* Honors, below the graphic. */
.mw-extras {
  padding-top: var(--step-3);
  border-top: 1px solid var(--border-strong);
}
.mw-extras ul { list-style: none; margin: 0; padding: 0; }
.mw-extras li { font-size: var(--step-0); line-height: 1.5; }
.mw-extras li + li { margin-top: var(--step-m2); }

@media (max-width: 1099.98px) {
  .mw-era-text.with-aside { display: block; }
  .mw-aside { max-width: 24em; margin-top: var(--step-1); }
}
@media (max-width: 699.98px) {
  .mw-head { padding-top: var(--step-3); }
  /* Spine on the left edge; prose and employers stack beside it. */
  .mw-era { grid-template-columns: var(--step-1) minmax(0, 1fr); column-gap: var(--step-0); }
  .mw-spine { grid-column: 1; grid-row: 1 / span 2; }
  .mw-era-text { grid-column: 2; padding-bottom: var(--step-0); }
  .mw-jobs { grid-column: 2; padding-top: 0; }
  .mw-era + .mw-era .mw-jobs { border-top: 0; }
}

/* ---------------------------------------------------------------
   12. Work history, horizontal (work-history-horizontal.html)
   The same content and scale as section 11, turned on its side: the
   four eras stand as columns, oldest on the left, with one spine
   running left to right through the middle. Each era's prose sits
   above the line and its employers below. The columns share rows
   through subgrid, so the spine lines up across all four whatever
   the length of each era's prose. Employer rows and tooltips reuse
   section 11's rules. Enterprise UX sits in Applied research's job
   list, as a labelled frame around Oracle, so it adds no height above
   the spine. Below 1000px the columns don't fit, so it falls back to
   the vertical layout with the spine on the left edge, newest first.
   --------------------------------------------------------------- */
.mh-chart {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: auto auto auto;
  padding-bottom: var(--step-3);
}
.mh-era {
  grid-row: 1 / span 3;
  display: grid;
  grid-template-rows: subgrid;
  min-width: 0;
}
.mh-era + .mh-era .mh-era-text,
.mh-era + .mh-era .mh-jobs { border-left: 1px solid var(--border); }
.mh-era-text, .mh-jobs { padding: var(--step-2) var(--step-1); min-width: 0; }
.mh-era:first-child .mh-era-text,
.mh-era:first-child .mh-jobs { padding-left: 0; }
.mh-era:last-child .mh-era-text,
.mh-era:last-child .mh-jobs { padding-right: 0; }
.mh-era-text { padding-top: var(--step-3); }
.mh-era-note { font-size: var(--step-m1); line-height: 1.55; text-wrap: pretty; }
.mh-era-text .mw-era-name { font-size: var(--step-1); }
.mh-jobs { list-style: none; margin: 0; }
/* Heading with the show-all toggle on the right. */
.mh-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--step-0) var(--step-2);
}
.mh-toggle {
  padding: var(--step-m2) var(--step-0);
  border: 1px solid var(--border-strong);
  background: none;
  color: var(--foreground);
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 500;
  cursor: pointer;
}
.mh-toggle:hover { border-color: var(--primary); color: var(--primary); }
.mh-toggle[aria-pressed="true"] { background: var(--foreground); border-color: var(--foreground); color: var(--background); }
.mh-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Tooltips fade and drop in briefly as they appear. */
@keyframes mh-tip-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}
.mh-chart .mw-tip { animation: mh-tip-in .16s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .mh-chart .mw-tip { animation: none; }
}

/* Show all: every description sits open under its job, in the flow,
   and the rows stop acting as tooltip buttons. */
.mh-chart.show-all .mw-tip {
  display: block;
  position: static;
  padding: var(--step-m2) 0 var(--step-m1);
  border: 0;
  background: none;
  font-size: var(--step-m1);
  animation: none;
}
/* The row above already gives role and dates. */
.mh-chart.show-all .mw-tip-meta { display: none; }
.mh-chart.show-all .mw-item { cursor: default; }
.mh-chart.show-all .mw-item::after { display: none; }
.mh-chart.show-all .mw-item:hover .mw-emp { color: inherit; }

/* Internships: the three placements listed under their group row. */
.mh-subjobs {
  list-style: none;
  margin: 0 0 var(--step-m1);
  padding-left: var(--step-0);
  border-left: 1px solid var(--border-strong);
  font-family: var(--sans);
  font-size: var(--step-m1);
  color: var(--muted-foreground);
}
.mh-subjobs li + li { margin-top: var(--step-m2); }

.mh-side {
  margin: var(--step-m2) 0;
  padding: var(--step-m1) var(--step-m1) 0;
  border: 1.5px solid var(--primary);
}
.mh-side-head {
  font-family: var(--sans);
  font-size: var(--step-m2);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--primary);
}
.mh-side-note {
  margin-top: 2px;
  font-size: var(--step-m1);
  line-height: 1.45;
  color: var(--muted-foreground);
  text-wrap: pretty;
}
.mh-side-jobs { list-style: none; margin: var(--step-m1) 0 0; padding: 0; }

/* The spine: a line across every column, a square marker at the start
   of each era (level with the text's left edge) and an arrowhead at
   the right end pointing to now. */
.mh-spine { position: relative; height: 13px; }
.mh-spine::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 3px;
  margin-top: -1.5px;
  background: var(--foreground);
}
.mh-spine::after {
  content: '';
  position: absolute;
  top: 0;
  left: var(--step-1);
  width: 13px; height: 13px;
  background: var(--primary);
}
.mh-era:first-child .mh-spine::after { left: 0; }
.mh-era:last-child .mh-spine::before { right: 12px; }
.mh-arrow {
  position: absolute;
  right: 0; top: 50%;
  margin-top: -8px;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  border-left: 13px solid var(--foreground);
}

@media (max-width: 999.98px) {
  /* Stacked, it reads newest first like experiences.html: the eras
     and each era's jobs are reversed on screen (the HTML stays oldest
     first for the columns above), so the arrowhead moves to the top. */
  .mh-chart { display: flex; flex-direction: column-reverse; }
  .mh-era {
    display: grid;
    grid-template-columns: var(--step-1) minmax(0, 1fr);
    grid-template-rows: auto auto;
    column-gap: var(--step-0);
  }
  .mh-era-text, .mh-jobs { grid-column: 2; padding: var(--step-2) 0 0; border-left: 0 !important; }
  .mh-jobs { display: flex; flex-direction: column-reverse; padding-top: var(--step-0); }
  .mh-era:not(:last-child) .mh-era-text { border-top: 1px solid var(--border); }
  /* Separators and spacing follow the on-screen order. */
  .mh-jobs > .mw-job + .mw-job { border-top: 0; border-bottom: 1px solid var(--border); }
  .mh-jobs > .mw-job:first-child .mw-item { padding-top: var(--step-m1); }
  .mh-jobs > .mw-job:last-child .mw-item { padding-top: 0; }
  .mh-spine { grid-column: 1; grid-row: 1 / span 2; height: auto; }
  .mh-spine::before { left: 50%; right: auto; top: 0; bottom: 0; width: 3px; height: auto; margin: 0 0 0 -1.5px; }
  .mh-spine::after, .mh-era:first-child .mh-spine::after { left: 50%; margin-left: -6.5px; top: calc(var(--step-2) + var(--step-1) * .55 - 6.5px); }
  .mh-era:first-child .mh-spine::before { bottom: var(--step-2); }
  .mh-era:last-child .mh-spine::before { right: auto; top: calc(var(--step-m1) + 10px); }
  .mh-arrow {
    top: var(--step-m1); right: auto; bottom: auto; left: 50%;
    margin: 0 0 0 -8px;
    border: 0;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-bottom: 13px solid var(--foreground);
  }
}

/* ---------------------------------------------------------------
   13. Work history, Gantt with eras (work-history-gantt.html)
   The dashboard page's timeline chart on section 10's scale, with
   the four eras built in: they head the chart and shade it in
   alternating bands behind the bars, and their prose sits below.
   Enterprise UX is a hatched band over Oracle's years. Years run
   left to right; each row is a button that opens section 11's
   tooltip, placed at the start of the row's bar (--s).
   --------------------------------------------------------------- */
.gx-chart {
  --label: clamp(11rem, 24%, 17rem);
  display: grid;
  grid-template-columns: var(--label) minmax(0, 1fr);
  grid-template-rows: auto auto auto;
  column-gap: var(--step-0);
  padding-top: var(--step-3);
}
.gx-head, .gx-bands, .gx-axis { grid-column: 2; position: relative; }

/* Era names alternate between two tiers, so a name wider than its
   era (Industrial UX is the narrowest) can run past its edge without
   meeting its neighbour's. The last one is right-aligned and runs left. */
.gx-head { grid-row: 1; height: calc((var(--step-1) * 1.2 + var(--step-m1) * 1.4) * 2 + var(--step-0)); }
.gx-era-label {
  position: absolute;
  top: 0; bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding: 0 var(--step-m2) var(--step-m1);
  border-left: 1px solid var(--border-strong);
  text-decoration: none;
  color: inherit;
}
.gx-era-label:nth-child(even) { justify-content: flex-end; }
.gx-era-label b { font-family: var(--serif); font-size: var(--step-1); font-weight: 400; line-height: 1.2; white-space: nowrap; }
.gx-era-label span { font-family: var(--sans); font-size: var(--step-m1); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--primary); white-space: nowrap; }
.gx-era-label:last-child { align-items: flex-end; text-align: right; padding-right: 0; }
/* Where a name runs over an era's edge, it masks the line. */
.gx-era-label b, .gx-era-label span { position: relative; z-index: 1; background: var(--background); }
.gx-era-label:hover b { color: var(--primary); }

.gx-bands { grid-row: 2; pointer-events: none; }
.gx-band { position: absolute; top: 0; bottom: 0; border-left: 1px solid var(--border-strong); }
.gx-band.alt { background: var(--muted); }
.gx-band.side {
  border: 1px dashed var(--primary);
  background: repeating-linear-gradient(135deg, var(--primary-soft) 0 6px, transparent 6px 12px);
}
.gx-band-note {
  position: absolute;
  bottom: var(--step-m2); left: var(--step-m2);
  font-family: var(--sans);
  font-size: var(--step-m2);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--primary);
  white-space: nowrap;
}

.gx-rows { grid-column: 1 / -1; grid-row: 2; list-style: none; margin: 0; padding: 0; position: relative; z-index: 1; }
.gx-row {
  position: relative;
  display: grid;
  grid-template-columns: var(--label) minmax(0, 1fr);
  column-gap: var(--step-0);
  border-top: 1px solid var(--border);
}
.gx-row:last-child { border-bottom: 1px solid var(--border); }
.gx-item {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: subgrid;
  align-items: center;
  width: 100%;
  padding: var(--step-m1) 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.gx-label { min-width: 0; }
.gx-emp { display: block; font-family: var(--serif); font-size: var(--step-1); line-height: 1.2; }
.gx-meta { display: block; font-family: var(--sans); font-size: var(--step-m1); color: var(--muted-foreground); }
.gx-track { position: relative; align-self: stretch; min-height: 14px; }
.gx-bar {
  position: absolute;
  top: 50%;
  height: 14px;
  margin-top: -7px;
  background: var(--primary);
}
.gx-bar.ongoing { background: linear-gradient(90deg, var(--primary) 70%, rgba(180, 84, 28, .3)); }
.gx-bar.dot { width: 12px; height: 12px; margin: -6px 0 0; }
.gx-bar.dot:first-child { margin-left: 0; }
.gx-bar.dot:not(:first-child) { margin-left: -6px; }
.gx-item:hover .gx-emp, .gx-item[aria-expanded="true"] .gx-emp { color: var(--primary); }
.gx-item:hover .gx-bar, .gx-item[aria-expanded="true"] .gx-bar { background: var(--foreground); }
.gx-item:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* The tooltip starts under the row's bar, kept inside the chart. */
.gx-tipbox { grid-column: 2; position: relative; height: 0; }
.gx-row .mw-tip {
  top: calc(-1 * var(--step-m2));
  left: clamp(0px, var(--s), calc(100% - min(30em, 100%)));
  right: auto;
  width: min(30em, 100%);
}
.gx-row:hover .mw-tip,
.gx-item[aria-expanded="true"] + .gx-tipbox .mw-tip,
.gx-item:focus-visible + .gx-tipbox .mw-tip,
.gx-row .mw-tip:focus-within { display: block; }

.gx-axis { grid-row: 3; height: calc(var(--step-m1) * 2); }
.gx-tick {
  position: absolute;
  top: 6px;
  transform: translateX(-50%);
  font-family: var(--sans);
  font-size: var(--step-m1);
  color: var(--muted-foreground);
}
.gx-tick::before { content: ''; position: absolute; top: -6px; left: 50%; height: 4px; border-left: 1px solid var(--border-strong); }
.gx-tick.first { transform: none; }
.gx-tick.first::before { left: 0; }
.gx-tick.last { transform: translateX(-100%); }
.gx-tick.last::before { left: auto; right: 0; }

/* The eras' prose, in date order below the chart. */
.gx-eras {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--step-3) var(--step-2);
  padding: var(--step-4) 0 var(--step-3);
}
.gx-era { border-top: 3px solid var(--foreground); padding-top: var(--step-0); }
.gx-era-name { font-size: var(--step-2); line-height: 1.15; font-weight: 400; }
.gx-era .mw-era-span { margin: var(--step-m2) 0 var(--step-0); }
.gx-era-note { font-size: var(--step-0); line-height: 1.5; text-wrap: pretty; }
.gx-aside {
  margin-top: var(--step-0);
  padding: var(--step-m1) var(--step-0);
  border: 1px dashed var(--primary);
  background: repeating-linear-gradient(135deg, var(--primary-soft) 0 6px, transparent 6px 12px);
  font-size: var(--step-m1);
  line-height: 1.5;
}
.gx-aside b { font-weight: 600; }
.gx-aside span { font-family: var(--sans); color: var(--primary); font-weight: 600; margin-right: .2em; }

@media (max-width: 1099.98px) {
  .gx-eras { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 699.98px) {
  /* One column: each row's label sits above its bar, which spans the
     full width; the era names stagger on two lines to fit. */
  .gx-chart, .gx-row { grid-template-columns: 0 minmax(0, 1fr); column-gap: 0; }
  .gx-item { grid-template-columns: 1fr; grid-column: 2; row-gap: var(--step-m2); }
  .gx-track { height: 14px; }
  .gx-emp { display: inline; font-size: var(--step-0); }
  .gx-meta { display: inline; }
  .gx-meta::before { content: ' · '; }
  .gx-head { height: 3.4em; }
  .gx-era-label { padding: 0 3px 4px; }
  .gx-era-label b { font-family: var(--sans); font-size: var(--step-m2); font-weight: 600; }
  .gx-era-label span { display: none; }
  .gx-era-label:last-child { border-left: 0; border-right: 1px solid var(--border-strong); }
  .gx-band-note { display: none; }
  .gx-tick.minor { display: none; }
  .gx-eras { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------
   14. Projects — modular scale + ratio grid (projects.html)
   Uses section 10's scale and 4 : 3 split, and section 11's header.
   The project index sits on the smaller side (3) and stays in view
   while the chosen case study fills the larger side (4). Every rule
   is scoped to .mp-page so it beats section 5's dashboard rules,
   which projects-dashboard.html still uses, at every width.
   --------------------------------------------------------------- */
.mp-layout {
  display: grid;
  grid-template-columns: var(--ratio-b) var(--ratio-a);
  column-gap: var(--step-4);
  align-items: start;
  padding-top: var(--step-3);
}
.mp-page .proj-nav { grid-area: auto; display: block; position: sticky; top: var(--step-2); }
.mp-page .proj-list {
  display: block;
  overflow: visible;
  gap: 0;
  padding: 0;
  border-top: 1px solid var(--border);
}
.mp-page .proj-list li { border-bottom: 1px solid var(--border); }
.mp-page .proj-tile {
  display: grid;
  grid-template-columns: 5.75em minmax(0, 1fr);
  column-gap: var(--step-0);
  align-items: baseline;
  height: auto;
  padding: var(--step-m1) 0 var(--step-m1) var(--step-0);
  background: none;
  border: 0;
  border-left: 3px solid transparent;
  box-shadow: none;
  color: var(--foreground);
  text-decoration: none;
}
.mp-year {
  grid-row: 1 / span 2;
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 600;
  color: var(--primary);
  white-space: nowrap;
}
.mp-title { font-family: var(--serif); font-size: var(--step-1); line-height: 1.2; }
.mp-topics {
  grid-column: 2;
  margin-top: .2em;
  font-family: var(--sans);
  font-size: var(--step-m1);
  color: var(--muted-foreground);
}
.mp-page .proj-tile:hover .mp-title { color: var(--primary); }
.mp-page .proj-tile[aria-current="true"] { border-left-color: var(--primary); background: var(--card); }
.mp-page .proj-tile:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* The case study. */
.mp-page .proj-detail {
  grid-area: auto;
  min-width: 0;
  overflow: visible;
  padding: 0;
  background: none;
  border: 0;
  scroll-margin-top: var(--step-2);
}
.mp-page .proj { max-width: 40em; }
.mp-page .proj + .proj { margin-top: var(--step-5); }
.js .mp-page .proj + .proj { margin-top: 0; }
.mp-page .proj-meta {
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--primary);
}
.mp-page .proj-title {
  margin: var(--step-m2) 0 var(--step-0);
  font-size: var(--step-3);
  font-weight: 400;
  line-height: 1.1;
  text-wrap: balance;
}
.mp-page .proj-subtitle {
  max-width: none;
  font-size: var(--step-1);
  line-height: 1.4;
  color: var(--muted-foreground);
  text-wrap: pretty;
}
.mp-page .facts {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: var(--step-2) 0;
}
.mp-page .fact { padding: var(--step-m1) var(--step-0); }
.mp-page .fact dt { font-size: var(--step-m2); margin-bottom: var(--step-m2); }
.mp-page .fact dd { font-size: var(--step-m1); line-height: 1.45; }
.mp-page .proj-hero {
  margin: var(--step-2) 0 0;
  font-size: var(--step-m2);
}
.mp-page .proj-body section { margin-top: var(--step-2); }
.mp-page .proj-body h3 {
  margin: 0 0 var(--step-m1);
  padding-top: var(--step-m1);
  border-top: 1px solid var(--border);
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--primary);
}
.mp-page .proj-body p,
.mp-page .proj-body ul,
.mp-page .proj-body ol { font-size: var(--step-0); line-height: 1.6; }
.mp-page .proj-body p + p { margin-top: var(--step-m1); }
.mp-page .proj-body ul, .mp-page .proj-body ol { padding-left: 1.2em; }
.mp-page .proj-body li + li { margin-top: var(--step-m2); }
.mp-page .proj-tags { gap: var(--step-m2); margin-top: var(--step-3); }
.mp-page .proj-tags span { padding: .2em .7em; font-size: var(--step-m1); }
.mp-page .proj-worklink { margin-top: var(--step-1); font-size: var(--step-m1); font-weight: 600; }

/* Below 1000px the index sits above the case study, two columns wide
   until phones, where it is one. */
@media (max-width: 999.98px) {
  .mp-layout { grid-template-columns: minmax(0, 1fr); row-gap: var(--step-4); }
  .mp-page .proj-nav { position: static; }
  .mp-page .proj-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--step-2); }
}
@media (max-width: 639.98px) {
  .mp-page .proj-list { grid-template-columns: minmax(0, 1fr); }
  .mp-page .facts { grid-template-columns: minmax(0, 1fr); }
  .mp-page .proj-tile { grid-template-columns: minmax(0, 1fr); padding-left: var(--step-m1); }
  .mp-year, .mp-topics { grid-row: auto; grid-column: 1; }
}

/* ---------------------------------------------------------------
   15. Projects — compact list + project panel (projects-list.html;
   projects.html builds on it, section 16)
   Builds on section 14 (the page also carries .mp-page) and
   overrides its layout. A compact list on the smaller side; the
   chosen project in a bordered panel on the larger side, leading
   with four key points set large for scanning. The full case study
   is folded into a <details> under them. Below 1000px v2.js moves
   the panel under its row, accordion style.
   The long-form page is kept as projects-longform.html.
   --------------------------------------------------------------- */
.mc-layout {
  display: grid;
  /* The list is narrower than the 4 : 3 split: 3 : 7, so the panel
     gets the room (Michael asked for the list a quarter narrower). */
  grid-template-columns: 3fr 7fr;
  column-gap: var(--step-3);
  align-items: start;
  padding-top: var(--step-3);
}
.mc-page .proj-tile {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: var(--step-0);
  padding: var(--step-m1) var(--step-0) var(--step-m1) var(--step-m1);
}
.mc-title { font-family: var(--serif); font-size: var(--step-0); line-height: 1.3; }
.mc-year {
  flex: none;
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 600;
  color: var(--primary);
  white-space: nowrap;
}
.mc-topics {
  grid-column: 1 / -1;
  margin-top: .15em;
  font-family: var(--sans);
  font-size: var(--step-m1);
  color: var(--muted-foreground);
}
.mc-page .proj-tile:hover .mc-title { color: var(--primary); }
.mc-page .proj-tile[aria-current="true"] .mc-title { color: var(--foreground); }

/* The panel: a dedicated, bordered space for the chosen project. */
.mc-page .proj-detail {
  padding: var(--step-2) var(--step-3) var(--step-3);
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-top: 3px solid var(--primary);
}
.mc-page .proj { max-width: none; }
.mc-page .proj + .proj { margin-top: var(--step-4); }
.js .mc-page .proj + .proj { margin-top: 0; }
.mc-page .proj-title { font-size: var(--step-3); }
.mc-page .proj-subtitle { font-size: var(--step-0); }

/* Key points: the part people scan, so it carries the weight. */
.mc-points {
  list-style: none;
  margin: var(--step-2) 0 0;
  padding: 0;
  border-top: 1px solid var(--border);
}
.mc-points li {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  column-gap: var(--step-0);
  align-items: baseline;
  padding: var(--step-0) 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--step-1);
  line-height: 1.35;
  text-wrap: pretty;
}
.mc-key {
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--primary);
}
.mc-page .proj-worklink { margin-top: var(--step-0); }

/* The full case study, folded. */
.mc-more { margin-top: var(--step-2); }
.mc-more > summary {
  display: inline-flex;
  align-items: center;
  gap: .6em;
  min-height: 44px;
  padding: 0 var(--step-0);
  border: 1px solid var(--border-strong);
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 500;
  cursor: pointer;
  list-style: none;
}
.mc-more > summary::-webkit-details-marker { display: none; }
.mc-more > summary::after { content: '+'; font-size: 1.3em; line-height: 1; color: var(--primary); }
.mc-more[open] > summary::after { content: '\2212'; }
.mc-more > summary:hover { border-color: var(--primary); color: var(--primary); }
.mc-more > summary:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.mc-more[open] > summary { margin-bottom: var(--step-0); }
.mc-page .facts { background: var(--border); }
.mc-page .fact { background: var(--card); }

/* Below 1000px: one column; the panel opens under its row. */
@media (max-width: 999.98px) {
  .mc-layout { grid-template-columns: minmax(0, 1fr); row-gap: var(--step-3); }
  .mc-page .proj-list { display: block; }
  .mc-page .proj-list .proj-detail { margin: 0 0 var(--step-0); padding: var(--step-0) var(--step-0) var(--step-2); }
  .js .mc-page .mc-layout > .proj-detail { display: none; }
}
@media (max-width: 639.98px) {
  .mc-page .proj-tile { display: grid; padding-left: var(--step-m1); }
  .mc-points li { grid-template-columns: minmax(0, 1fr); row-gap: var(--step-m2); font-size: var(--step-0); }
  .mc-page .facts { grid-template-columns: minmax(0, 1fr); }
}

/* Section 15, continued: the project's entrance. Each time a project
   is shown (display: none to block restarts the animation) the whole
   article fades and rises a few pixels as one piece, composited on the
   GPU so the text doesn't shimmer; the four key points follow with a
   short, opacity-only stagger. The full case study fades in when it
   is unfolded. Off for reduced motion. */
@keyframes mc-rise { from { opacity: 0; transform: translate3d(0, 6px, 0); } to { opacity: 1; transform: translate3d(0, 0, 0); } }
@keyframes mc-fade { from { opacity: 0; } to { opacity: 1; } }
.js .mc-page .proj.is-shown { animation: mc-rise .28s cubic-bezier(.25, .8, .3, 1) both; }
.js .mc-page .proj.is-shown .mc-points li { animation: mc-fade .3s ease-out both; }
.js .mc-page .proj.is-shown .mc-points li:nth-child(1) { animation-delay: .06s; }
.js .mc-page .proj.is-shown .mc-points li:nth-child(2) { animation-delay: .1s; }
.js .mc-page .proj.is-shown .mc-points li:nth-child(3) { animation-delay: .14s; }
.js .mc-page .proj.is-shown .mc-points li:nth-child(4) { animation-delay: .18s; }
.mc-more[open] > :not(summary) { animation: mc-fade .25s ease-out both; }
@media (prefers-reduced-motion: reduce) {
  .js .mc-page .proj.is-shown,
  .js .mc-page .proj.is-shown .mc-points li,
  .mc-more[open] > :not(summary) { animation: none; }
}

/* Section 15, continued: project images. A lead image floats in the
   panel's top right beside the heading; figures sit full width in the
   case study with a small caption. */
.mc-page .proj-lead-img {
  float: right;
  width: clamp(7rem, 24%, 254px);
  height: auto;
  margin: 0 0 var(--step-0) var(--step-1);
}
.mc-page .mc-points { clear: both; }
.mc-page .proj-fig { margin: var(--step-1) 0 0; }
.mc-page .proj-fig img { display: block; width: auto; max-width: 100%; height: auto; border: 1px solid var(--border); }
.mc-page .proj-fig figcaption {
  margin-top: var(--step-m2);
  font-family: var(--sans);
  font-size: var(--step-m1);
  color: var(--muted-foreground);
}
/* Two narrow images, such as phone screens, side by side. */
.mc-page .proj-fig-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--step-0);
  max-width: 34rem;
}
.mc-page .proj-fig + .proj-fig { margin-top: var(--step-0); }

/* ---------------------------------------------------------------
   16. Projects with tiles (projects-grid.html; projects.html builds
   on it, section 17)
   Builds on section 15 (the page also carries .mp-page and
   .mc-page). The six projects sit in a row of tiles across the top;
   the chosen project spreads across the full width below them,
   unboxed, its key points in a 2 x 2 grid. Long text keeps a
   readable measure. Tablets get the tiles 3 x 2; below 640px v2.js
   falls back to section 15's accordion list.
   --------------------------------------------------------------- */
.mt-page .mc-layout { grid-template-columns: minmax(0, 1fr); row-gap: var(--step-3); }
.mt-page .proj-nav { position: static; }

@media (min-width: 640px) {
  .mt-page .proj-list {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: var(--step-m1);
    border-top: 0;
  }
  .mt-page .proj-list li { border-bottom: 0; }
  .mt-page .proj-tile {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: var(--step-m1) var(--step-0) var(--step-0);
    border: 0;
    border-top: 1px solid var(--border-strong);
    background: none;
  }
  .mt-page .proj-tile .mc-year { order: -1; margin-bottom: var(--step-m2); }
  .mt-page .proj-tile .mc-title { font-size: var(--step-1); line-height: 1.2; }
  .mt-page .proj-tile .mc-topics { margin-top: var(--step-m2); }
  .mt-page .proj-tile:hover { border-top-color: var(--primary); }
  .mt-page .proj-tile[aria-current="true"] {
    border-top: 3px solid var(--primary);
    padding-top: calc(var(--step-m1) - 2px);
    background: var(--card);
  }
  /* Tablets keep the panel below the tiles, not in the list. */
  .js .mt-page .mc-layout > .proj-detail { display: block; }
}
@media (min-width: 640px) and (max-width: 999.98px) {
  .mt-page .proj-list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* The project: unboxed, full width. */
@media (min-width: 640px) {
  .mt-page .proj-detail { padding: 0; background: none; border: 0; }
}
.mt-page .proj-title { font-size: var(--step-4); line-height: 1.1; text-wrap: balance; }
.mt-page .proj-subtitle { max-width: 40rem; margin-top: var(--step-m1); }
.mt-page .proj-lead-img { width: clamp(8rem, 26%, 254px); margin-left: var(--step-3); }

/* Key points: 2 x 2, the label above its text. */
@media (min-width: 640px) {
  .mt-page .mc-points {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--step-3);
    margin-top: var(--step-3);
    border-top: 0;
  }
  .mt-page .mc-points li {
    grid-template-columns: minmax(0, 1fr);
    align-content: start;
    row-gap: var(--step-m2);
    padding: var(--step-0) 0 var(--step-1);
    border-top: 1px solid var(--border-strong);
    border-bottom: 0;
  }
}

/* The full case study keeps a readable line length. */
.mt-page .mc-more > :not(summary) { max-width: 46rem; }

/* Previous and next projects, at the foot of each one. */
.mt-steps {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--step-2);
  margin-top: var(--step-3);
  padding-top: var(--step-0);
  border-top: 1px solid var(--border-strong);
}
.mt-steps a {
  font-family: var(--serif);
  font-size: var(--step-1);
  line-height: 1.25;
  color: var(--foreground);
  text-decoration: none;
}
.mt-steps a span {
  display: block;
  margin-bottom: var(--step-m2);
  font-family: var(--sans);
  font-size: var(--step-m2);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--primary);
}
.mt-steps a:hover { color: var(--primary); }
.mt-steps a:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.mt-steps .mt-next { grid-column: 2; text-align: right; }
@media (max-width: 639.98px) {
  .mt-page .proj-title { font-size: var(--step-3); }
  .mt-steps a { font-size: var(--step-0); }
}

/* ---------------------------------------------------------------
   17. Projects, key points in one column (projects-column.html;
   projects.html builds on it, section 18). Builds
   on section 16. The heading runs full width; below it the four key
   points run down one column, with the intro image to their right in
   a narrower column (7 : 3) so the text stays dominant. A tighter top
   than section 16, so the first points show on a laptop screen.
   Below 640px it is section 16's phone layout unchanged.
   --------------------------------------------------------------- */
@media (min-width: 640px) {
  .mk-page .proj {
    display: grid;
    /* The photo's column is kept narrow so the text stays dominant. */
    grid-template-columns: 7fr 3fr;
    column-gap: var(--step-3);
    align-items: start;
  }
  .mk-page .proj > * { grid-column: 1 / -1; }
  /* No photo: the points take a wider measure instead. */
  .mk-page .proj:not(:has(.proj-lead-img)) > .mc-points { grid-column: 1 / -1; max-width: 56rem; }
  .mk-page .proj-meta { grid-row: 1; }
  .mk-page .proj-title { grid-row: 2; }
  .mk-page .proj-subtitle { grid-row: 3; }
  .mk-page .proj > .mc-points { grid-row: 4; grid-column: 1; }
  .mk-page .proj > .proj-lead-img {
    grid-row: 4;
    grid-column: 2;
    float: none;
    width: auto;
    max-width: 100%;
    margin: var(--step-3) 0 0;
  }
  .mk-page .proj-worklink { grid-row: 5; }
  .mk-page .mc-more { grid-row: 6; }
  .mk-page .mt-steps { grid-row: 7; }

  .mk-page .mc-points { display: block; border-top: 0; }
  .mk-page .mc-points li {
    grid-template-columns: 6.5rem minmax(0, 1fr);
    align-items: baseline;
    padding: var(--step-0) 0;
    border-top: 0;
  }
  /* Only the outer lines: one above the first point, one under the last. */
  .mk-page .mc-points { border-top: 1px solid var(--border-strong); }
  .mk-page .mc-points li:last-child { border-bottom: 1px solid var(--border-strong); }
  .mk-page .proj-title { margin-bottom: 0; }
}
/* A tighter top, so the first key points show on a laptop screen
   without scrolling. */
.mk-page .mw-head { padding: var(--step-3) 0 0; border-bottom: 0; }
.mk-page .ms-name { font-size: var(--step-4); }
.mk-page .mc-layout { padding-top: var(--step-1); row-gap: var(--step-2); }
.mk-page .proj > .proj-meta { margin-bottom: 0; }
.mk-page .proj > .proj-title { font-size: var(--step-3); }
.mk-page .mc-points { margin-top: var(--step-1); }
@media (min-width: 640px) {
  .mk-page .proj-tile { padding: var(--step-m1) var(--step-0) var(--step-m1); }
  .mk-page .proj-tile[aria-current="true"] { padding-top: calc(var(--step-m1) - 2px); }
  .mk-page .proj-tile .mc-year { margin-bottom: var(--step-m2); }
  .mk-page .proj-tile .mc-title { font-size: var(--step-0); }
  .mk-page .proj > .proj-lead-img { margin-top: var(--step-1); }
}
/* Tablets: the column is narrow, so each label sits above its text. */
@media (min-width: 640px) and (max-width: 999.98px) {
  .mk-page .mc-points li { grid-template-columns: minmax(0, 1fr); row-gap: var(--step-m2); }
}

/* ---------------------------------------------------------------
   18. Projects, two-column case study (projects.html). Builds on section 17. From 1000px the full case study
   uses the same 7 : 3 split as the key points and intro image above:
   each section's heading sits in a label column, its text beside it, and its figures (grouped in
   .proj-figs) on the right, under the intro image. One reading
   order, top to bottom. Narrower screens keep section 17's layout.
   --------------------------------------------------------------- */
@media (min-width: 1000px) {
  .ks-page .mc-more > :not(summary) { max-width: none; }
  .ks-page .proj-body section {
    display: grid;
    grid-template-columns: 7fr 3fr;
    column-gap: var(--step-3);
    align-items: start;
    padding-top: var(--step-0);
    border-top: 1px solid var(--border-strong);
  }
  /* Section headings are longer than the key-point labels, so the
     label column is wider here and they wrap within it. */
  .ks-page .proj-body section > * { grid-column: 1; padding-left: calc(10rem + var(--step-1)); }
  .ks-page .proj-body section > ul,
  .ks-page .proj-body section > ol { padding-left: calc(10rem + var(--step-1) + 1.2em); }
  .ks-page .proj-body section > h3 {
    grid-row: 1;
    width: 10rem;
    padding: .35em 0 0;
    margin: 0;
    border-top: 0;
    line-height: 1.45;
    text-wrap: balance;
  }
  .ks-page .proj-body section > h3 + * { grid-row: 1; }
  .ks-page .proj-body section > .proj-figs {
    grid-column: 2;
    grid-row: 1 / span 30;
    padding-left: 0;
  }
  .ks-page .proj-figs .proj-fig:first-child { margin-top: 0; }
  .ks-page .proj-figs .proj-fig-pair { max-width: none; }
  .ks-page .proj-hero,
  .ks-page .proj-tags { margin-left: calc(10rem + var(--step-1)); }
}

/* Image placeholders, until real images arrive (Data Platform). */
.proj-ph {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  padding: 0 var(--step-0);
  text-align: center;
  background: repeating-linear-gradient(135deg, var(--muted) 0 10px, #e9e2d6 10px 11px);
  font-family: var(--sans);
  font-size: var(--step-m2);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-foreground);
}
.mc-page .proj-fig .proj-ph { max-width: 34rem; }
@media (min-width: 640px) {
  .mk-page .proj > .proj-lead-img.proj-ph { width: 100%; }
}

/* Section 18, continued: the employer link and the case-study button
   move into the photo column. The link sits opposite the project's
   summary; the button (made by v2.js, replacing the <summary>) sits
   at the foot of the column, level with the end of the key points. */
.js .ks-page .mc-more > summary { display: none; }
.js .ks-page .mc-more[open] { margin-top: var(--step-2); }
.mc-toggle {
  display: inline-flex;
  align-items: center;
  gap: .6em;
  min-height: 44px;
  margin-top: var(--step-1);
  padding: 0 var(--step-0);
  border: 1px solid var(--border-strong);
  border-radius: 0;
  background: none;
  color: var(--foreground);
  font-family: var(--sans);
  font-size: var(--step-m1);
  font-weight: 500;
  cursor: pointer;
}
.mc-toggle::after { content: '+'; font-size: 1.3em; line-height: 1; color: var(--primary); }
.mc-toggle[aria-expanded="true"]::after { content: '\2212'; }
.mc-toggle:hover { border-color: var(--primary); color: var(--primary); }
.mc-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
@media (min-width: 640px) {
  .ks-page .proj > .proj-meta,
  .ks-page .proj > .proj-title,
  .ks-page .proj > .proj-subtitle { grid-column: 1; }
  .ks-page .proj > .proj-worklink {
    grid-row: 3;
    grid-column: 2;
    align-self: end;
    margin: 0;
  }
  .ks-page .proj > .mc-toggle {
    grid-row: 4;
    grid-column: 2;
    align-self: end;
    justify-self: start;
    margin: 0;
  }
  .js .ks-page .proj > .mc-more:not([open]) { display: none; }
}

/* Section 17, continued: no lines between the key points at any width,
   only the outer two. */
.mk-page .mc-points li { border-bottom: 0; }
.mk-page .mc-points li:last-child { border-bottom: 1px solid var(--border-strong); }

/* Section 18, continued: more air between the row of tiles and the
   project, and between the project and the previous/next section. */
.ks-page .mc-layout { row-gap: var(--step-4); padding-top: var(--step-2); }
.ks-page .mt-steps { margin-top: var(--step-5); padding-top: var(--step-1); }
@media (max-width: 639.98px) {
  .ks-page .mt-steps { margin-top: var(--step-4); }
}

/* Section 18, continued: a stronger highlight for the selected project.
   The tile takes a tinted background and its title the accent colour;
   on wide screens the top bar doubles in weight, on phones the left
   bar does. */
.ks-page .proj-tile[aria-current="true"] { background: var(--primary-soft); }
.ks-page .proj-tile[aria-current="true"] .mc-title { color: var(--primary); }
@media (min-width: 640px) {
  .ks-page .proj-tile[aria-current="true"] {
    border-top: 6px solid var(--primary);
    padding-top: calc(var(--step-m1) - 5px);
  }
}
@media (max-width: 639.98px) {
  .ks-page .proj-tile[aria-current="true"] {
    border-left-width: 6px;
    padding-left: calc(var(--step-m1) - 3px);
  }
}

/* Section 18, continued: no lines between the case study's sections;
   one rule above the first, and the tags at the foot are gone. */
.ks-page .proj-body { border-top: 1px solid var(--border-strong); }
.ks-page .proj-body h3 { border-top: 0; padding-top: 0; }
.ks-page .proj-body section { margin-top: var(--step-3); }
@media (min-width: 1000px) {
  .ks-page .proj-body section { border-top: 0; padding-top: 0; }
  .ks-page .proj-body section > h3 { padding-top: .35em; }
}

/* Section 18, continued: the project's entrance on this page is one
   even fade of the whole project at once. No rise, and the key points
   no longer follow one after another, so nothing moves while it runs. */
.js .ks-page .proj.is-shown { animation: mc-fade .3s ease-out both; }
.js .ks-page .proj.is-shown .mc-points li { animation: none; }

/* Section 18, continued: the key points sit between two rules that run
   the full width of the page; the intro image starts just under the top
   one. The case-study toggle is a small borderless link at the right,
   below the lower rule and above the case study, which has no rule of
   its own. */
.ks-page .proj-body { border-top: 0; }
.ks-page .mc-toggle {
  display: flex;
  min-height: 36px;
  margin: var(--step-0) 0 0;
  padding: 0;
  border: 0;
  background: none;
  font-size: .8rem;
  color: var(--primary);
}
.ks-page .mc-toggle:hover { border: 0; }
.ks-page .mc-toggle:hover span { text-decoration: underline; text-underline-offset: 3px; }
@media (min-width: 640px) {
  .ks-page .proj::before,
  .ks-page .proj::after {
    content: '';
    grid-column: 1 / -1;
    border-top: 1px solid var(--border-strong);
  }
  .ks-page .proj::before { grid-row: 4; margin-top: var(--step-1); }
  .ks-page .proj::after { grid-row: 6; }
  .ks-page .proj > .mc-points { grid-row: 5; grid-column: 1; margin-top: 0; border-top: 0; }
  .ks-page .mc-points li:last-child { border-bottom: 0; }
  .ks-page .proj > .proj-lead-img { grid-row: 5; grid-column: 2; margin-top: var(--step-0); }
  .ks-page .proj > .mc-toggle { grid-row: 7; grid-column: 1 / -1; justify-self: start; align-self: start; margin: var(--step-0) 0 0; }
  .ks-page .proj > .mc-more { grid-row: 8; }
  .ks-page .proj > .mt-steps { grid-row: 9; }
}

/* Section 18, continued: the previous/next links have no rule above them
   and sit at the foot of the page, just above the footer. When the project
   is shorter than the window the project stretches to fill what is left, so
   the links drop to the bottom; when the page scrolls they just follow the
   content. */
.ks-page .mt-steps { border-top: 0; padding-top: 0; }
@media (min-width: 640px) {
  .ks-page .mc-layout { flex: 1 0 auto; grid-template-rows: auto minmax(0, 1fr); }
  .js .ks-page .mc-layout > .proj-detail { display: flex; flex-direction: column; align-self: stretch; }
  .ks-page .proj-detail > .proj { flex: 1 0 auto; grid-template-rows: repeat(8, auto) minmax(0, 1fr); }
  .ks-page .proj > .mt-steps { align-self: end; }
}

/* Section 18, continued: case-study images open larger in a dialog. */
.ks-page img.zoomable { cursor: zoom-in; }
.ks-page img.zoomable:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
.zoom {
  max-width: none;
  max-height: none;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: var(--step-2);
  border: 0;
  background: transparent;
  color: #fff;
  cursor: zoom-out;
}
.zoom[open] { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--step-0); }
.zoom::backdrop { background: rgba(33, 29, 25, .88); }
.zoom img {
  display: block;
  max-width: 100%;
  max-height: calc(100dvh - 7rem);
  width: auto;
  height: auto;
  background: #fff;
}
.zoom p { margin: 0; max-width: 40rem; text-align: center; font-family: var(--sans); font-size: .85rem; }
.zoom-close {
  position: absolute;
  top: var(--step-0);
  right: var(--step-1);
  width: 44px;
  height: 44px;
  border: 0;
  background: none;
  color: #fff;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}
.zoom-close:focus-visible { outline: 2px solid #fff; outline-offset: -4px; }

/* Section 18, continued: no topic line above the title (the selected tile
   already shows it); the link to the job sits under the summary; the
   case-study toggle is a little larger and bolder so it reads as the next
   step. */
.ks-page .proj > .proj-meta { display: none; }
.ks-page .mc-toggle { font-size: var(--step-0); font-weight: 600; gap: .4em; }
@media (min-width: 640px) {
  .ks-page .proj > .proj-title { grid-row: 1; }
  .ks-page .proj > .proj-subtitle { grid-row: 2; }
  .ks-page .proj > .proj-worklink { grid-row: 3; grid-column: 1; align-self: start; margin: var(--step-m1) 0 0; }
}
/* The job link sits on the title's line, in the image column. */
@media (min-width: 640px) {
  .ks-page .proj > .proj-worklink { grid-row: 1; grid-column: 2; align-self: center; margin: 0; }
}

/* Section 18, continued: the job link closes the summary under the title. */
.ks-page .proj-joblink { color: var(--primary); text-decoration: none; white-space: nowrap; }
.ks-page .proj-joblink:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Section 18, continued: less above the project, so more of it shows on
   a laptop screen: a smaller page heading set closer to the menu, tiles
   with one topic each, and a shorter gap between the tiles and the
   project. */
.ks-page .mw-head { padding-top: var(--step-2); }
.ks-page .ms-name { font-size: var(--step-3); }
.ks-page .mc-layout { padding-top: var(--step-0); row-gap: var(--step-3); }
@media (min-width: 640px) {
  .ks-page .proj-tile { padding-bottom: var(--step-m1); }
  .ks-page .proj-tile .mc-topics { margin-top: var(--step-m2); }
}

/* Experience: the page heading matches the Projects heading in size and
   in its distance from the menu. */
.mh-head { padding-top: var(--step-2); }
.mh-head .ms-name { font-size: var(--step-3); }

/* Projects: the project title is a step smaller than the page heading. */
.ks-page .proj > .proj-title { font-size: var(--step-2); }

/* Section 18, continued: the row of project tiles sits in its own panel,
   a light fill inside a border, so it reads apart from the project below.
   Tiles lose their own top rules; the selected tile is lifted out of the
   fill (the lighter card colour) with an orange bar along its top. */
@media (min-width: 640px) {
  .ks-page .proj-list {
    padding: var(--step-m1);
    gap: var(--step-m2);
    background: var(--muted);
    border: 1px solid var(--border-strong);
  }
  .ks-page .proj-tile,
  .ks-page .proj-tile[aria-current="true"] {
    padding: var(--step-m1) var(--step-0);
    border: 0;
    border-top: 3px solid transparent;
    background: none;
  }
  .ks-page .proj-tile:hover { border-top-color: var(--border-strong); background: rgba(255, 255, 255, .35); }
  .ks-page .proj-tile[aria-current="true"],
  .ks-page .proj-tile[aria-current="true"]:hover {
    border-top-color: var(--primary);
    background: var(--card);
  }
}

/* Section 18, continued: grouped figures enlarge as a whole. Two images
   that belong together either overlap (the larger at top left, the
   smaller over its lower right corner, ringed in the page colour) or sit
   side by side. With two columns, v2.js sets --fit-h so the images take
   the height of the text beside them. */
.ks-page .proj-fig-group .proj-fig-imgs { position: relative; }
.ks-page .proj-figs { min-width: 0; }
.ks-page .proj-fig-stack .proj-fig-imgs { width: 100%; aspect-ratio: 4 / 3; }
.ks-page .proj-fig-stack[style*="--fit-h"] .proj-fig-imgs { aspect-ratio: auto; height: var(--fit-h); }
.ks-page .proj-fig-stack .proj-fig-imgs img {
  position: absolute;
  width: auto;
  max-width: none;
  object-fit: contain;
}
.ks-page .proj-fig-stack .proj-fig-imgs img:first-child { left: 0; top: 0; height: 74%; max-width: 86%; object-position: left top; }
.ks-page .proj-fig-stack .proj-fig-imgs img:last-child {
  right: 0;
  bottom: 0;
  height: 50%;
  max-width: 62%;
  object-position: right bottom;
  outline: 5px solid var(--background);
}
.ks-page .proj-fig-pair { display: block; max-width: none; }
.ks-page .proj-fig-pair .proj-fig-imgs { display: flex; gap: var(--step-0); height: var(--fit-h, auto); }
.ks-page .proj-fig-pair .proj-fig-imgs img { min-width: 0; height: 100%; width: auto; max-width: calc(50% - var(--step-0) / 2); object-fit: contain; }
.ks-page .proj-fig-pair:not([style*="--fit-h"]) .proj-fig-imgs img { height: auto; }
.ks-page .proj-fig-group figcaption { margin-top: var(--step-m1); }

.zoom-imgs { display: flex; justify-content: center; gap: var(--step-1); max-width: 100%; }
.zoom-imgs img {
  display: block;
  min-width: 0;
  max-width: calc((100vw - 4 * var(--step-2)) / var(--n, 1));
  max-height: calc(100dvh - 9rem);
  width: auto;
  height: auto;
  background: #fff;
}

/* Images narrower than their column sit in its centre. */
.ks-page .proj-fig > img { margin-left: auto; margin-right: auto; }
.ks-page .proj-fig-pair .proj-fig-imgs { justify-content: center; }

/* Experience: "Show all job descriptions" is a switch, a squared track
   whose knob slides right and fills orange when on. The label stays the
   same either way. */
.mh-toggle,
.mh-toggle:hover,
.mh-toggle[aria-pressed="true"] {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--step-m1);
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--foreground);
}
.mh-toggle::after {
  content: '';
  flex: none;
  width: 2.6em;
  height: 1.4em;
  border: 1px solid var(--border-strong);
  background:
    linear-gradient(var(--muted-foreground), var(--muted-foreground)) left 3px center / calc(1.4em - 8px) calc(1.4em - 8px) no-repeat,
    var(--card);
  transition: background-position .15s ease-out;
}
.mh-toggle:hover::after { border-color: var(--primary); }
.mh-toggle[aria-pressed="true"]::after {
  border-color: var(--primary);
  background:
    linear-gradient(#fff, #fff) right 3px center / calc(1.4em - 8px) calc(1.4em - 8px) no-repeat,
    var(--primary);
}
@media (prefers-reduced-motion: reduce) { .mh-toggle::after { transition: none; } }

/* The "i" in the job rows' info boxes sits in the middle of its box. */
.mw-item::after {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  line-height: 1;
  padding-right: .08em;
}

/* The "i" in the info boxes is drawn, not typed: a letter sits wherever
   the loaded font puts it, a drawing sits dead centre. */
.mw-item::after {
  content: '';
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Ccircle cx='6.55' cy='3.1' r='1' fill='%236e675e'/%3E%3Cpath d='M5.75 5h1.25l-.85 4.9H4.9z' fill='%236e675e'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}
.mw-item:hover::after, .mw-item[aria-expanded="true"]::after {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Ccircle cx='6.55' cy='3.1' r='1' fill='%23fff'/%3E%3Cpath d='M5.75 5h1.25l-.85 4.9H4.9z' fill='%23fff'/%3E%3C/svg%3E") center / 100% 100% no-repeat, var(--primary);
}

/* The info glyph is Tabler's "info-square" icon (MIT, tabler.io/icons),
   its "i" only: the box is this rule's own squared border. */
.mw-item::after {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='3 3.5 18 18' fill='none' stroke='%236e675e' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 9h.01'/%3E%3Cpath d='M11 12h1v4h1'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}
.mw-item:hover::after, .mw-item[aria-expanded="true"]::after {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='3 3.5 18 18' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 9h.01'/%3E%3Cpath d='M11 12h1v4h1'/%3E%3C/svg%3E") center / 100% 100% no-repeat, var(--primary);
}

/* A plain "i" (a dot over a bar) reads better at this size than the
   icon stroke did. The box sits level with the
   employer name, the first line of the row. */
.mw-item::after {
  grid-row: 1;
  align-self: center;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='5.9' r='1.2' fill='%236e675e'/%3E%3Crect x='9.25' y='8.6' width='1.5' height='7.2' fill='%236e675e'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}
.mw-item:hover::after, .mw-item[aria-expanded="true"]::after {
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='5.9' r='1.2' fill='%23fff'/%3E%3Crect x='9.25' y='8.6' width='1.5' height='7.2' fill='%23fff'/%3E%3C/svg%3E") center / 100% 100% no-repeat, var(--primary);
}

/* Experience: descriptions ease in. A hovered tooltip fades in over a
   quarter second as it settles; with "Show all job descriptions" on,
   every description fades in together. Off for reduced motion. */
.mh-chart .mw-tip { animation: mh-tip-in .25s ease-out; }
.mh-chart.show-all .mw-tip { animation: mc-fade .35s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .mh-chart .mw-tip,
  .mh-chart.show-all .mw-tip { animation: none; }
}

/* Home: the role sits beside the name, on its baseline, in plain muted
   type; when the line runs out of room it drops underneath. */
.ms-namerow {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--step-1);
  row-gap: var(--step-m1);
}
.ms-role {
  margin: 0;
  font-size: var(--step-1);
  color: var(--muted-foreground);
}
/* On wide screens the pair stays on one line, running into the gap
   before the portrait rather than wrapping inside the text column. */
@media (min-width: 1100px) {
  /* contain keeps the long line from widening the text column. */
  .ms-namerow { flex-wrap: nowrap; contain: inline-size; }
  .ms-namerow > * { flex: none; white-space: nowrap; }
}

/* Orange means "you can click this" or "you are here", nothing else.
   Static labels (footer and section labels, era dates, Enterprise UX,
   key-point labels, case-study headings, tile years) are in ink; links
   in running text are underlined as well as orange. */
body.ms-page .ms-footer-label,
body.ms-page .ms-eyebrow,
body.ms-page .mw-era-span,
body.ms-page .mh-side-head,
body.ms-page .mc-key,
body.ms-page .proj-body h3,
body.ms-page .proj-tile .mc-year { color: var(--foreground); }
body.ms-page .mh-side { border-color: var(--foreground); }
body.ms-page .proj-joblink { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
body.ms-page .proj-joblink:hover { text-decoration-thickness: 2px; }

/* Orange means clickable, and only that. Unselected menu links and
   project tiles are orange; the page or project you are on turns ink,
   marked by an ink bar (under the menu link, above the lifted tile, or
   beside the row on phones). Hover underlines instead of recolouring. */
body.ms-page .ms-nav .menu-links a { color: var(--primary); }
body.ms-page .ms-nav .menu-links a:hover { color: var(--primary); border-bottom-color: currentColor; }
body.ms-page .ms-nav .menu-links a[aria-current="page"],
body.ms-page .ms-nav .menu-links a[aria-current="page"]:hover {
  color: var(--foreground);
  border-bottom-color: var(--foreground);
}
.ks-page .proj-tile .mc-title { color: var(--primary); }
.ks-page .proj-tile:hover .mc-title { color: var(--primary); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.ks-page .proj-tile[aria-current="true"] .mc-title,
.ks-page .proj-tile[aria-current="true"]:hover .mc-title { color: var(--foreground); text-decoration: none; }
.ks-page .proj-tile[aria-current="true"] { background: var(--card); border-color: var(--foreground); }
@media (min-width: 640px) {
  .ks-page .proj-tile[aria-current="true"],
  .ks-page .proj-tile[aria-current="true"]:hover { border-top-color: var(--foreground); }
}
.ks-page .proj-detail { border-top-color: var(--foreground); }

/* Menu underlines run exactly the width of their word: the space between
   links is a gap, not padding inside them. */
body.ms-page .ms-nav .menu-links { gap: calc(var(--step-m1) * 2); }
body.ms-page .ms-nav .menu-links a { padding: 0; }
/* Exceptions to "orange means clickable": the Enterprise UX frame and the
   timeline's era markers stay orange. */
body.ms-page .mh-side { border-color: var(--primary); }
