/* Grateful Dev AI — shared styles. Self-hosted display font, no external assets, no runtime requests. */

/*
  Scene: a small, real software studio's public site, read once by an Apple
  reviewer at a desk during business hours deciding whether this is a
  legitimate company, and later by a founder or collaborator sizing the
  studio up before a call. Electric, high-contrast, neon-outline energy on
  a true near-black field — like blacklight concert-poster signage — while
  every word stays effortlessly legible. Red/white/blue is the primary
  voice; the earlier warm sunset spectrum survives only as a faint,
  low-alpha secondary glow underneath it.

  Every bloom/glow color below is capped per-surface at a peak alpha
  verified by script (WCAG contrast of body text and dimmed text against
  the fully composited color, worst case at the blob's own peak, no scrim
  tricks hiding the math).

  Frame ornament is generated botanical/Art-Nouveau rose-vine artwork
  (art/, processed by art/process_art.py into transparent foil/tint PNGs),
  not hand-authored SVG. Roses and psychedelic styling only: no skulls,
  lightning bolts, bears, terrapins, or any reproduction of a third-party
  mark.
*/

@font-face {
  font-family: "Fraunces";
  src: url("fonts/Fraunces-Variable.ttf") format("truetype-variations"),
       url("fonts/Fraunces-Variable.ttf") format("truetype");
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Canvas: true near-black with a hint of blue, not neutral gray-black. */
  --bg: oklch(9% 0.025 258);
  --bg-alt: oklch(12% 0.03 258);
  --bg-raised: oklch(15% 0.035 258);
  --border: oklch(55% 0.08 250 / 45%);
  --text: oklch(97% 0.006 250);
  --text-dim: oklch(80% 0.03 250);

  /* Electric primary trio. */
  --crimson: oklch(63% 0.24 25);
  --crimson-strong: oklch(70% 0.22 25);
  --blue: oklch(68% 0.17 250);
  --blue-strong: oklch(75% 0.15 250);

  /* Sunset spectrum retired to a faint secondary glow only (see the wash rules). */
  --rose: oklch(62% 0.22 15);
  --orange: oklch(70% 0.18 45);
  --gold: oklch(85% 0.16 88);
  --teal: oklch(74% 0.12 188);
  --violet: oklch(58% 0.18 300);

  --accent: var(--blue);
  --accent-strong: var(--blue-strong);

  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --max-width: 960px;
  --measure: 68ch;

  /*
    Real generated engraving artwork (art/), not hand-authored linework.
    Two prior hand-drawn-SVG ornament attempts read as lifeless/synthetic;
    this site now uses actual botanical/Art-Nouveau plates, processed
    (ink -> alpha, tinted/foiled) by art/process_art.py. PNG is the base
    value; browsers that support image-set() get the lighter WebP instead
    (see the @supports block below). Rose plate is reused at varied
    scale/rotation/opacity inside one baked wallpaper tile so the repeat
    reads as poster wallpaper, not a mechanical grid.
  */
  --img-rose-wallpaper: url("art/rose-wallpaper-tile.png");
  --img-corner-tl: url("art/corner-foil-tl.png");
  --img-corner-tr: url("art/corner-foil-tr.png");
  --img-corner-bl: url("art/corner-foil-bl.png");
  --img-corner-br: url("art/corner-foil-br.png");
  --img-border-h: url("art/border-foil-h.png");
  --img-border-v: url("art/border-foil-v.png");
}

/* WebP is ~50% lighter than the PNG source; fall back to PNG (above)
   wherever image-set() with a type() hint isn't understood. */
@supports (background-image: image-set(url("data:,") 1x)) {
  :root {
    --img-rose-wallpaper: image-set(url("art/rose-wallpaper-tile.webp") type("image/webp") 1x, url("art/rose-wallpaper-tile.png") type("image/png") 1x);
    --img-corner-tl: image-set(url("art/corner-foil-tl.webp") type("image/webp") 1x, url("art/corner-foil-tl.png") type("image/png") 1x);
    --img-corner-tr: image-set(url("art/corner-foil-tr.webp") type("image/webp") 1x, url("art/corner-foil-tr.png") type("image/png") 1x);
    --img-corner-bl: image-set(url("art/corner-foil-bl.webp") type("image/webp") 1x, url("art/corner-foil-bl.png") type("image/png") 1x);
    --img-corner-br: image-set(url("art/corner-foil-br.webp") type("image/webp") 1x, url("art/corner-foil-br.png") type("image/png") 1x);
    --img-border-h: image-set(url("art/border-foil-h.webp") type("image/webp") 1x, url("art/border-foil-h.png") type("image/png") 1x);
    --img-border-v: image-set(url("art/border-foil-v.webp") type("image/webp") 1x, url("art/border-foil-v.png") type("image/png") 1x);
  }
}

* {
  box-sizing: border-box;
}

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

body {
  position: relative;
  /* The poster frame bleeds slightly outside main's own box into the page
     gutter; this guarantees it can never introduce a horizontal scrollbar
     at in-between viewport widths. */
  overflow-x: hidden;
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  line-height: 1.6;
  font-size: 17px;
}

/*
  Continuous secondary glow: fixed behind every page, low alpha, mostly
  crimson/blue with a faint ghost of the old sunset hues. Bottom layer is
  a solid, opaque var(--bg) fill so this never compounds with the local
  washes on .hero/.card/footer.site, which each carry their own opaque
  base and occlude this layer completely.
*/
body::before {
  content: "";
  position: fixed;
  inset: -20%;
  z-index: -2;
  background:
    radial-gradient(circle at 10% 6%, color-mix(in oklch, var(--crimson) 16%, transparent) 0%, transparent 30%),
    radial-gradient(circle at 92% 4%, color-mix(in oklch, var(--blue) 14%, transparent) 0%, transparent 28%),
    radial-gradient(circle at 90% 62%, color-mix(in oklch, var(--teal) 8%, transparent) 0%, transparent 32%),
    radial-gradient(circle at 8% 68%, color-mix(in oklch, var(--violet) 12%, transparent) 0%, transparent 30%),
    radial-gradient(circle at 50% 100%, color-mix(in oklch, var(--gold) 6%, transparent) 0%, transparent 34%),
    var(--bg);
  background-size: 130% 130%;
  background-position: 0% 0%;
  filter: blur(70px);
  animation: page-drift 110s ease-in-out infinite alternate;
}

/* Fine paper grain on top of the wash. Pure CSS, no network request. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

@keyframes page-drift {
  from {
    background-position: 0% 0%;
  }
  to {
    background-position: 10% 8%;
  }
}

@media (prefers-reduced-motion: reduce) {
  body::before {
    animation: none;
  }
}

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

a:hover,
a:focus-visible {
  text-decoration: underline;
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

img {
  max-width: 100%;
}

.wrap {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 24px;
}

header.site {
  position: sticky;
  top: 0;
  z-index: 10;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}

/* The red/white/blue ribbon: the smallest color move on the page. */
header.site::before {
  content: "";
  display: block;
  height: 4px;
  background: linear-gradient(90deg, var(--crimson), var(--text), var(--blue));
  box-shadow: 0 0 10px color-mix(in oklch, var(--blue) 45%, transparent);
}

.nav-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  padding: 18px 0;
}

.brand {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 24, "SOFT" 15, "WONK" 0;
  font-size: 1.15rem;
  color: var(--text);
  letter-spacing: -0.01em;
}

.brand:hover,
.brand:focus-visible {
  text-decoration: none;
  color: var(--blue);
}

.brand .brand-mark {
  color: var(--crimson);
}

nav.primary ul {
  list-style: none;
  display: flex;
  gap: 24px;
  margin: 0;
  padding: 0;
  flex-wrap: wrap;
}

nav.primary a {
  color: var(--text-dim);
  font-weight: 500;
  font-size: 0.95rem;
}

nav.primary a[aria-current="page"] {
  color: var(--text);
  border-bottom: 2px solid var(--blue);
  padding-bottom: 2px;
}

main {
  position: relative;
  max-width: calc(var(--max-width) + 96px);
  margin: 32px auto 0;
  padding: 56px 48px 72px;
  border: 1px solid color-mix(in oklch, var(--gold) 40%, var(--border));
  border-radius: 2px;
  box-shadow:
    0 0 16px color-mix(in oklch, var(--crimson) 40%, transparent),
    0 0 26px color-mix(in oklch, var(--blue) 22%, transparent);
  /* One place to tune the frame; the breakpoints below just shrink these. */
  /* Thick enough that the engraved vine reads as linework, not gold static. */
  --frame-inset: 22px;
  --frame-corner: 130px;
  --frame-thick: 92px;
}

/*
  Poster frame: real generated Art-Nouveau rose-vine artwork (art/), baked
  to transparent gold foil by art/process_art.py (ink -> alpha, banded
  metallic gradient fill). Four corner medallions plus tiling top/bottom
  and left/right strips, sitting just outside main's own border in the
  page gutter so the ornament never crowds the content padding.
*/
main::before {
  content: "";
  position: absolute;
  inset: calc(var(--frame-inset) * -1);
  pointer-events: none;
  background-repeat:
    no-repeat, no-repeat, no-repeat, no-repeat,
    repeat-x, repeat-x, repeat-y, repeat-y;
  background-image:
    var(--img-corner-tl),
    var(--img-corner-tr),
    var(--img-corner-bl),
    var(--img-corner-br),
    var(--img-border-h),
    var(--img-border-h),
    var(--img-border-v),
    var(--img-border-v);
  background-position:
    top left,
    top right,
    bottom left,
    bottom right,
    top left,
    bottom left,
    top left,
    top right;
  background-size:
    var(--frame-corner) var(--frame-corner),
    var(--frame-corner) var(--frame-corner),
    var(--frame-corner) var(--frame-corner),
    var(--frame-corner) var(--frame-corner),
    auto var(--frame-thick),
    auto var(--frame-thick),
    var(--frame-thick) auto,
    var(--frame-thick) auto;
  filter: drop-shadow(0 0 6px color-mix(in oklch, var(--gold) 55%, transparent));
}

/*
  Rose motif: the real rose-plate engraving, tinted and reused at varied
  scale/rotation/opacity inside one baked tile (art/process_art.py), tiled
  behind content. Same color and same 0.16 opacity as the ornament this
  replaces, so the proven worst-case contrast (a rose stroke directly under
  --text-dim body copy on --bg, 8.9:1, past the 4.5:1 AA floor) still holds:
  identical composite math, only the source image changed.
*/
main::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--img-rose-wallpaper);
  background-repeat: repeat;
  background-size: 400px 400px;
  opacity: 0.16;
}

main .wrap {
  position: relative;
}

.hero {
  position: relative;
  padding: 40px 0 40px;
  margin-bottom: 8px;
}

/*
  Liquid-light wash at genuinely visible strength: an opaque var(--bg) base
  (blocks the global wash beneath from compounding) topped with electric
  crimson/blue blooms plus a faint violet ghost of the old sunset palette,
  each capped at the peak alpha verified against var(--bg) for both text
  tokens.
*/
.hero::before {
  content: "";
  position: absolute;
  /* Bleed past the poster field's padding so no hard rectangle edge shows. */
  top: -10%;
  bottom: -10%;
  left: -48px;
  right: -48px;
  border-radius: 2px;
  z-index: -1;
  background:
    radial-gradient(circle at 8% 0%, color-mix(in oklch, var(--crimson) 50%, transparent) 0%, transparent 42%),
    radial-gradient(circle at 94% 4%, color-mix(in oklch, var(--blue) 40%, transparent) 0%, transparent 40%),
    radial-gradient(circle at 85% 82%, color-mix(in oklch, var(--blue) 30%, transparent) 0%, transparent 46%),
    radial-gradient(circle at 6% 84%, color-mix(in oklch, var(--crimson) 40%, transparent) 0%, transparent 44%),
    radial-gradient(circle at 50% 50%, color-mix(in oklch, var(--violet) 18%, transparent) 0%, transparent 55%),
    var(--bg);
  background-size: 130% 130%;
  background-position: 0% 0%;
  filter: blur(45px);
  animation: hero-drift 70s ease-in-out infinite alternate;
}

@keyframes hero-drift {
  from {
    background-position: 0% 0%;
  }
  to {
    background-position: 12% 10%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero::before {
    animation: none;
  }
}

.hero h1 {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 60, "SOFT" 20, "WONK" 1;
  font-size: clamp(2.1rem, 5vw, 3.1rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
  margin: 0 0 20px;
  text-shadow:
    0 0 10px color-mix(in oklch, var(--crimson) 55%, transparent),
    0 0 26px color-mix(in oklch, var(--blue) 40%, transparent);
}

.hero .lede {
  font-size: 1.2rem;
  color: var(--text-dim);
  max-width: 42ch;
}

h1, h2, h3 {
  color: var(--text);
  font-weight: 700;
}

h2 {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 30, "SOFT" 10, "WONK" 0;
  font-size: 1.7rem;
  margin: 2.6em 0 0.6em;
  padding-bottom: 0.3em;
  letter-spacing: -0.01em;
  border-bottom: 1px solid var(--border);
  text-shadow: 0 0 8px color-mix(in oklch, var(--blue) 40%, transparent);
}

h2:first-of-type {
  margin-top: 1.4em;
}

h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "opsz" 20, "SOFT" 10, "WONK" 0;
  font-size: 1.35rem;
  margin: 1.8em 0 0.5em;
  text-shadow: 0 0 6px color-mix(in oklch, var(--crimson) 35%, transparent);
}

p {
  margin: 0 0 1.1em;
  max-width: var(--measure);
  color: var(--text-dim);
}

.hero p.entity {
  color: var(--text);
}

strong {
  color: var(--text);
}

ul, ol {
  color: var(--text-dim);
  padding-left: 1.3em;
}

li {
  margin-bottom: 0.5em;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
  margin: 24px 0 40px;
}

.card {
  position: relative;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 22px 24px;
  overflow: hidden;
}

/* Contained bloom, one hue per card, alpha capped against var(--bg-raised). */
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(
    circle at 100% 0%,
    color-mix(in oklch, var(--bloom, var(--crimson)) 38%, transparent) 0%,
    transparent 65%
  );
}

.card > * {
  position: relative;
  z-index: 1;
}

.card:nth-of-type(2) {
  --bloom: var(--blue);
}

.card:nth-of-type(3) {
  --bloom: var(--violet);
}

.card h3 {
  margin-top: 0;
}

.status-tag {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--blue);
  background: color-mix(in oklch, var(--blue) 14%, transparent);
  border: 1px solid color-mix(in oklch, var(--blue) 55%, transparent);
  border-radius: 999px;
  padding: 3px 10px;
  margin-bottom: 10px;
  box-shadow: 0 0 8px color-mix(in oklch, var(--blue) 30%, transparent);
}

.callout {
  position: relative;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 24px;
  margin: 32px 0;
  max-width: none;
  overflow: hidden;
}

.callout::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(
    circle at 0% 100%,
    color-mix(in oklch, var(--crimson) 32%, transparent) 0%,
    transparent 60%
  );
}

.callout > * {
  position: relative;
  z-index: 1;
}

.callout p {
  max-width: var(--measure);
}

.callout p:last-child {
  margin-bottom: 0;
}

.contact-block {
  position: relative;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 28px 30px;
  margin: 24px 0;
  overflow: hidden;
}

.contact-block::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(
    circle at 100% 100%,
    color-mix(in oklch, var(--blue) 34%, transparent) 0%,
    transparent 60%
  );
}

.contact-block > * {
  position: relative;
  z-index: 1;
}

.contact-block dt {
  font-weight: 600;
  color: var(--text);
  margin-top: 16px;
}

.contact-block dt:first-child {
  margin-top: 0;
}

.contact-block dd {
  margin: 4px 0 0;
  color: var(--text-dim);
}

/* Outline-and-glow, not a filled swatch: transparent field, stroked edge, halo. */
.btn {
  display: inline-block;
  background: transparent;
  color: var(--crimson);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 0.85rem;
  padding: 10px 22px;
  border: 2px solid var(--crimson);
  border-radius: 6px;
  margin-top: 10px;
  box-shadow: 0 0 10px color-mix(in oklch, var(--crimson) 50%, transparent);
}

.btn:hover,
.btn:focus-visible {
  background: color-mix(in oklch, var(--crimson) 15%, transparent);
  color: var(--text);
  box-shadow: 0 0 18px color-mix(in oklch, var(--crimson) 70%, transparent);
  text-decoration: none;
}

footer.site {
  position: relative;
  border-top: 1px solid var(--border);
  padding: 32px 0;
  color: var(--text-dim);
  font-size: 0.9rem;
  overflow: hidden;
}

footer.site::before {
  content: "";
  position: absolute;
  inset: -10%;
  z-index: -1;
  background:
    radial-gradient(circle at 10% 100%, color-mix(in oklch, var(--blue) 32%, transparent) 0%, transparent 42%),
    radial-gradient(circle at 90% 100%, color-mix(in oklch, var(--crimson) 32%, transparent) 0%, transparent 42%),
    radial-gradient(circle at 50% 0%, color-mix(in oklch, var(--violet) 14%, transparent) 0%, transparent 40%),
    var(--bg);
  filter: blur(50px);
}

footer.site .wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

footer.site nav ul {
  list-style: none;
  display: flex;
  gap: 18px;
  margin: 0;
  padding: 0;
}

footer.site a {
  color: var(--text-dim);
}

@media (max-width: 700px) {
  main {
    max-width: none;
    margin: 16px 12px 0;
    padding: 36px 24px 48px;
    /* Frame thins down and pulls inside the smaller page gutter rather
       than crowding content or risking edge clipping. */
    --frame-inset: 8px;
    --frame-corner: 52px;
    --frame-thick: 18px;
  }
}

@media (max-width: 480px) {
  main::before {
    display: none;
  }

  main {
    box-shadow: 0 0 12px color-mix(in oklch, var(--crimson) 45%, transparent);
  }
}

@media (max-width: 600px) {
  body {
    font-size: 16px;
  }

  .nav-bar {
    flex-direction: column;
    align-items: flex-start;
  }

  footer.site .wrap {
    flex-direction: column;
    align-items: flex-start;
  }
}
