/* gramaz.io stylesheet — 1960s / mid-century refresh. */

/* ===== Base: fonts, layout, spacing ===== */

@font-face { font-family: "SS4"; src: url("font/SourceSerif4-Regular.otf.woff2"); font-weight: 400; }
@font-face { font-family: "SS4"; src: url("font/SourceSerif4-It.otf.woff2"); font-weight: 400; font-style: italic; }
@font-face { font-family: "SS4"; src: url("font/SourceSerif4-Light.otf.woff2"); font-weight: 300; }
@font-face { font-family: "SS4"; src: url("font/SourceSerif4-Semibold.otf.woff2"); font-weight: 600; }
@font-face { font-family: "SS4"; src: url("font/SourceSerif4-Bold.otf.woff2"); font-weight: 700; }

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

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

body {
  margin: 0;
  font-family: "SS4", "Times New Roman", Times, serif;
  font-size: 1.125rem;
  line-height: 1.65;
}

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

.wrap {
  max-width: 800px;
  margin: 0 auto;
  padding: 0 20px;
}

/* ---------- intro ---------- */
.intro-inner {
  display: grid;
  grid-template-columns: minmax(110px, 1fr) 3fr;
  gap: 2.5rem;
  align-items: center;
  padding-top: 3.5rem;
  padding-bottom: 3.5rem;
}
.portrait { margin: 0; position: relative; }
.portrait img { border-radius: 9999px; position: relative; z-index: 1; }
.whoami h1 { margin: 0; line-height: 1; }
.roles { list-style: none; margin: 1rem 0 0; padding: 0; }
.roles li { line-height: 1.5; }

@media (max-width: 560px) {
  .intro-inner { grid-template-columns: 1fr; gap: 1.75rem; }
  .portrait { max-width: 160px; }
}

/* ---------- main ---------- */
.main-content { padding-top: 2.5rem; padding-bottom: 3rem; }
.main-content section { margin-bottom: 3.5rem; }
.main-content h2 { margin: 0 0 1.25rem; line-height: 1.1; }
.main-content h3 { margin: 2rem 0 0.5rem; font-size: 1.4rem; line-height: 1.2; }
.main-content h4 { margin: 0.5rem 0; font-size: 1.125rem; font-weight: 400; }
.main-content p { margin: 0 0 1.1rem; }
.main-content ul { padding-left: 1.25rem; margin: 0 0 1.1rem; }
.main-content li { margin-bottom: 0.5rem; }
.main-content ul.plain { list-style: none; padding-left: 1.25rem; }
.main-content ul.plain li { margin-bottom: 0.15rem; }

strong { font-weight: 600; }
em { font-style: italic; }

/* ---------- footer ---------- */
.footer { padding: 2.5rem 0 5rem; }
.footer p { margin: 0 0 0.5rem; }
.footer .fine { margin-top: 1rem; font-size: 0.95rem; }


/* ===== Theme ===== */
/* Variant H7 — "Script Stack + Goo Roles" (H6 with gooey role pills) (A's layered stack + H1's Yellowtail, in D2's palette)
   Built on D2 — "Mid-Century Blue"
   Variant D's 1960s structure (slab display face, double-struck skewed slabs,
   offset portrait circles, wave) in the original site's blue + grayscale palette. */

:root {
  --sky: #eef6ff;       /* original header wash */
  --paper: #ffffff;
  --ink: #333333;       /* original text + slabs */
  --blue: rgb(0, 119, 255);
  --powder: #bcd8eb;    /* original secondary blue */
  --gray: #dddddd;      /* original h2 pill */
  --mid: #666666;
}

body { color: var(--ink); }

/* Overscroll colours. iOS Safari 26 ignores theme-color and paints the area
   past either end of the page (and behind its status bar and toolbar) with
   the body background. So the body carries the edge colour: sky while you're
   in the top half, ink (the footer) in the bottom half, switched by a
   scroll-driven animation. Browsers without animation-timeline just keep sky.
   <main> paints its own full-width white so the body colour never shows
   through the page itself (box-shadow + clip-path is the full-bleed trick). */
html, body { background: var(--sky); }
@supports (animation-timeline: scroll()) {
  body { animation: edge-bg linear both; animation-timeline: scroll(root); }
}
@keyframes edge-bg {
  0%, 49.9% { background-color: var(--sky); }
  50%, 100% { background-color: var(--ink); }
}
main {
  background: var(--paper);
  box-shadow: 0 0 0 100vmax var(--paper);
  clip-path: inset(0 -100vmax);
}
::selection { background: var(--blue); color: #fff; }

/* ---------- intro ---------- */
.intro { background: var(--sky); }
/* Layered ocean swells: four wind-leaning silhouettes, back to front.
   viewBox is cropped with "slice" so crests never stretch on narrow screens. */
/* W6: ridgeline swells — stacked ridges that hide the ones behind them
   (Unknown-Pleasures-style ridgeline), with cusped crests. Back ridges fade
   toward the sky: lower contrast and thinner lines. Generated by ridges.py. */
.wave { display: block; width: 100%; height: 110px; margin-top: -1px; overflow: hidden; }
.wave .sea-sky { fill: var(--sky); }
.wave .ridge-line { fill: none; stroke-linejoin: miter; stroke-miterlimit: 8;
  vector-effect: non-scaling-stroke; }
.wave .ridge.r0 { fill: color-mix(in srgb, var(--paper) 0%, var(--sky)); }
.wave .ridge-line.r0 { stroke: color-mix(in srgb, var(--blue) 22%, var(--sky)); stroke-width: 0.5; }
.wave .ridge.r1 { fill: color-mix(in srgb, var(--paper) 12%, var(--sky)); }
.wave .ridge-line.r1 { stroke: color-mix(in srgb, var(--blue) 38%, var(--sky)); stroke-width: 0.58; }
.wave .ridge.r2 { fill: color-mix(in srgb, var(--paper) 25%, var(--sky)); }
.wave .ridge-line.r2 { stroke: color-mix(in srgb, var(--blue) 54%, var(--sky)); stroke-width: 0.72; }
.wave .ridge.r3 { fill: color-mix(in srgb, var(--paper) 38%, var(--sky)); }
.wave .ridge-line.r3 { stroke: color-mix(in srgb, var(--blue) 71%, var(--sky)); stroke-width: 0.88; }
.wave .ridge.r4 { fill: color-mix(in srgb, var(--paper) 50%, var(--sky)); }
.wave .ridge-line.r4 { stroke: color-mix(in srgb, var(--blue) 87%, var(--sky)); stroke-width: 1.07; }
.wave .ridge.r5 { fill: color-mix(in srgb, var(--paper) 62%, var(--sky)); }
.wave .ridge-line.r5 { stroke: color-mix(in srgb, var(--ink) 6%, var(--blue)); stroke-width: 1.28; }
.wave .ridge.r6 { fill: color-mix(in srgb, var(--paper) 75%, var(--sky)); }
.wave .ridge-line.r6 { stroke: color-mix(in srgb, var(--ink) 38%, var(--blue)); stroke-width: 1.5; }
.wave .ridge.r7 { fill: color-mix(in srgb, var(--paper) 88%, var(--sky)); }
.wave .ridge-line.r7 { stroke: color-mix(in srgb, var(--ink) 69%, var(--blue)); stroke-width: 1.74; }
.wave .ridge.r8 { fill: color-mix(in srgb, var(--paper) 100%, var(--sky)); }
.wave .ridge-line.r8 { stroke: color-mix(in srgb, var(--ink) 100%, var(--blue)); stroke-width: 2.0; }
@media (max-width: 600px) { .wave { height: 84px; } }
/* /W6 wave */


.portrait { isolation: isolate; }
.portrait::before,
.portrait::after {
  content: "";
  position: absolute;
  border-radius: 9999px;
  z-index: -1;
}
.portrait::before { background: var(--powder); top: -5%; left: -5%; width: 105%; height: 105%; }
.portrait::after  { background: var(--blue);   top: 6%;  left: 6%;  width: 100%; height: 100%; z-index: -2; }

/* Variant A's receding stack, applied to H1's Yellowtail script.
   One real text node; the blue and ink layers are text-shadows, so screen
   readers, copy/paste, find-in-page and reader mode all see the name once. */
/* The name is sized against its own column (cqi), not the viewport, so it can
   never outgrow the space beside the portrait. One line of the script is ~6.5em wide. */
.whoami { perspective: 900px; container-type: inline-size; }
.stack {
  --d: 0.045em;   /* blue layer's step back from the white script */
  --d2: 0.02em;   /* ink layer's extra step behind the blue; keep < --d so blue reads thicker */
  --k: 0.014em;  /* keyline around the blue layer (~ half the front stroke) */
  margin: 0;
  padding: 0.2em 0 0em;
  font-family: "Yellowtail", "Brush Script MT", cursive;
  font-weight: 400;
  font-size: clamp(2.4rem, 15.5cqi, 5.5rem);
  line-height: 1;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: #fff;
  -webkit-text-stroke: 0.05em var(--ink);
  paint-order: stroke fill;
  /* First shadow paints on top: blue layer, its ink keyline, then the ink layer. */
  text-shadow:
    var(--d) var(--d) 0 var(--blue),
    calc(var(--d) + var(--k)) var(--d) 0 var(--ink),
    calc(var(--d) - var(--k)) var(--d) 0 var(--ink),
    var(--d) calc(var(--d) + var(--k)) 0 var(--ink),
    var(--d) calc(var(--d) - var(--k)) 0 var(--ink),
    calc(var(--d) + var(--d2)) calc(var(--d) + var(--d2)) 0 var(--ink),
    calc(var(--d) + var(--d2) + var(--k)) calc(var(--d) + var(--d2) + var(--k)) 0 var(--ink);
  transform: rotateY(-10deg) rotateX(6deg) rotateZ(-3deg);
  transform-origin: left center;
}

.defs { position: absolute; width: 0; height: 0; }
/* Inside-border color of the gooey roles blob (the feFlood in the #goo filter). */
.goo-border { flood-color: #444; }

/* Roles: stacked pills melted together by the #goo filter, with an offset blue
   copy (drop-shadow) echoing the name's stacked layers. */
.roles {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin: 1rem 0 0 0.4rem;
  padding: 0;
  list-style: none;
  filter: url(#goo) drop-shadow(5px 5px 0 var(--blue));
}
.roles li {
  margin: 0;
  padding: 0.1em 0.9em;
  background: var(--paper);
  color: var(--ink);
  font-family: "Source Sans 3", "Source Sans Pro", system-ui, sans-serif;
  font-weight: 400;
  font-size: 1.1rem;
  line-height: 1.25;
  letter-spacing: 0.01em;
}
.roles li:first-child { font-weight: 600; padding-top: 0.45em; }
.roles li:last-child { padding-bottom: 0.45em; }

.stack br { display: none; }
/* phone: one centred column; the name stays on one line, sized to the column
   by the cqi clamp above */
@media (max-width: 560px) {
  .intro-inner { justify-items: center; text-align: center; }
  .whoami { justify-self: stretch; } /* keep full width: it's the cqi container */
  .stack { transform-origin: center; }
  .roles { margin: 1.6rem auto 0; align-items: center; }
}

/* ---------- main ---------- */
/* Section headings: the name's white/blue/ink Yellowtail stack, scaled down. */
.main-content h2 {
  font-family: "Yellowtail", "Brush Script MT", cursive;
  font-weight: 400;
  line-height: 1.1;
  color: #fff;
  -webkit-text-stroke: 0.05em var(--ink);
  paint-order: stroke fill;
  --d: 0.045em; --d2: 0.02em; --k: 0.014em;
  text-shadow:
    var(--d) var(--d) 0 var(--blue),
    calc(var(--d) + var(--k)) var(--d) 0 var(--ink),
    calc(var(--d) - var(--k)) var(--d) 0 var(--ink),
    var(--d) calc(var(--d) + var(--k)) 0 var(--ink),
    var(--d) calc(var(--d) - var(--k)) 0 var(--ink),
    calc(var(--d) + var(--d2)) calc(var(--d) + var(--d2)) 0 var(--ink);
  font-size: 2.6rem;
  letter-spacing: 0.01em;
  margin: 0 0 1rem;
  transform: rotate(-2deg);
  transform-origin: left center;
}

.main-content h3 {
  font-family: "Source Sans 3", "Source Sans Pro", system-ui, sans-serif;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--blue);
  margin-top: 2rem;
}

/* Bold lead-in sentences: a gooey highlight (see #goo-hl in the HTML).
   Vertical padding makes the wrapped lines overlap so they merge; side padding
   comes from the filter. Background must be opaque (the filter keys on alpha). */
.main-content section > p > strong:first-child,
.main-content li strong {
  background: var(--hl);
  padding: 0.3em 0;
  filter: url(#goo-hl);
  /* The filter widens the shape ~7px each side and paints over neighbours, so
     keep adjacent text clear. Inline margins only apply at the ends (first/last line). */
  margin-inline: 0.25em;
}
.main-content section > p > strong:first-child { margin-left: 0; } /* stays flush with the column */
/* iOS WebKit paints a stray black rectangle at the top-left of the page when
   an SVG filter sits on these inline elements. Promoting each one to its own
   compositing layer makes it draw the filter correctly. -webkit-touch-callout
   is only supported on iOS, so desktop browsers skip this. */
@supports (-webkit-touch-callout: none) {
  .main-content section > p > strong:first-child,
  .main-content li strong { will-change: filter; }
}
:root { --hl: color-mix(in srgb, var(--blue) 18%, var(--paper)); }
.goo-hl-fill { flood-color: var(--hl); }
.main-content ul:not(.plain) li::marker { color: var(--blue); }

a { color: var(--blue); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { background: rgba(0, 119, 255, 0.25); }

/* footer waves — generated by footer_ridges.py; mirrors the header ridgeline,
   fading from the white page into the footer's ink through grey. */
.wave-foot { display: block; width: 100%; height: 72px; margin-bottom: -1px; overflow: hidden;
  background: var(--paper); } /* the sky above the ridges; body is ink here (see overscroll colours) */
.wave-foot .fr-line { fill: none; stroke-linejoin: miter; stroke-miterlimit: 8; vector-effect: non-scaling-stroke; }
.wave-foot .fr.r0 { fill: color-mix(in srgb, var(--ink) 0%, var(--paper)); }
.wave-foot .fr-line.r0 { stroke: color-mix(in srgb, var(--mid) 25%, var(--paper)); stroke-width: 0.5; }
.wave-foot .fr.r1 { fill: color-mix(in srgb, var(--ink) 8%, var(--paper)); }
.wave-foot .fr-line.r1 { stroke: color-mix(in srgb, var(--mid) 43%, var(--paper)); stroke-width: 0.67; }
.wave-foot .fr.r2 { fill: color-mix(in srgb, var(--ink) 23%, var(--paper)); }
.wave-foot .fr-line.r2 { stroke: var(--blue); stroke-width: 0.9; }
.wave-foot .fr.r3 { fill: color-mix(in srgb, var(--ink) 44%, var(--paper)); }
.wave-foot .fr-line.r3 { stroke: var(--blue); stroke-width: 1.15; }
.wave-foot .fr.r4 { fill: color-mix(in srgb, var(--ink) 70%, var(--paper)); }
.wave-foot .fr-line.r4 { stroke: #8a8a8a; stroke-width: 1.42; }
.wave-foot .fr.r5 { fill: color-mix(in srgb, var(--ink) 100%, var(--paper)); }
.wave-foot .fr-line.r5 { stroke: #8a8a8a; stroke-width: 1.7; }
@media (max-width: 600px) { .wave-foot { height: 56px; } }
/* /footer waves */

/* ---------- footer ---------- */
.footer { background: var(--ink); color: #fff; }
.footer strong { color: #fff; }

/* Contact row: tracked-caps label (like the h3 subheads) + a pill built like
   the role blob (white fill, sans, blue offset shadow). */
.footer .contact { display: flex; align-items: center; flex-wrap: wrap; gap: 0.9rem; }
.contact-label {
  font-family: "Source Sans 3", "Source Sans Pro", system-ui, sans-serif;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--powder);
}
.contact-pill {
  display: inline-block;
  font-family: "Source Sans 3", "Source Sans Pro", system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1;
  color: var(--ink);
  background: var(--paper);
  text-decoration: none;
  padding: 0.55em 1.1em 0.5em;
  border-radius: 0.8em;
  /* Three shadows, always in this order so every state tweens smoothly
     (box-shadow only interpolates when the lists match in length and inset-ness):
       1. inside border (powder blue, all sides)
       2. hard inset shadow: no blur, no spread, at the same 45° as the outer
          offset, so it lands on the inner top/left edges, opposite the blue
       3. outer blue offset
     Nothing translates, so the label never moves. */
  --pill-border: var(--powder);           /* all-sides inside border */
  --pill-inset: rgb(0 0 0 / 0.18);        /* translucent black, hard edge */
  --pill-bw: 2px;                         /* border width */
  --pill-d: 3px;                          /* visible depth of the inset shadow */
  box-shadow:
    inset 0 0 0 0 transparent,
    inset 0 0 0 0 transparent,
    4px 4px 0 var(--blue);
  transition: box-shadow 0.18s ease;
}
/* hover: powder-blue inside border + a hard, translucent black inset shadow fade in; face stays white */
.contact-pill:hover {
  background: var(--paper);               /* keep the face white (overrides global a:hover tint) */
  box-shadow:
    inset 0 0 0 var(--pill-bw) var(--pill-border),
    inset calc(var(--pill-bw) + var(--pill-d)) calc(var(--pill-bw) + var(--pill-d)) 0 0 var(--pill-inset),
    4px 4px 0 var(--blue);
}
/* pressed: the inset deepens; still no movement */
.contact-pill:active {
  background: var(--paper);
  box-shadow:
    inset 0 0 0 var(--pill-bw) var(--pill-border),
    inset calc(var(--pill-bw) + var(--pill-d) * 2) calc(var(--pill-bw) + var(--pill-d) * 2) 0 0 var(--pill-inset),
    4px 4px 0 var(--blue);
}
.contact-pill:focus-visible { outline: 2px solid var(--powder); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .contact-pill { transition: none; } }

.footer .fine { color: #ababab; }  /* ~5.6:1 on --ink, meets WCAG AA for small text */
