/* marlindalpozzo.com — one stylesheet, no build. Light and dark follow the system setting. */

@font-face {
  font-family: Graphik;
  src: url(/fonts/Graphik-Regular.ttf) format('truetype');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: Graphik;
  src: url(/fonts/Graphik-Medium.ttf) format('truetype');
  font-weight: 600;
  font-display: swap;
}

:root {
  color-scheme: light dark;
  --bg: #fff;
  --text: #0a0a0a;
  --soft: #404040;
  --muted: #737373;
  --hover: #262626;
  --line: #e5e5e5;
  --divider: #a1a1aa;
  --surface: #fafafa;
  --surface-hover: #f2f2f2;
  --tag: #f0f0f0;
  --link: #1d4ed8;
  --field: #f5f5f5;
  --field-border: #d4d4d4;
  --focus: #47a3f3;
  --nav-mark: linear-gradient(to left, transparent, #a3a3a3);
  --ok: #15803d;
  --error: #dc2626;
}
/* Dark: follows the device unless the footer toggle forced a theme (<html data-theme="light|dark">). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #111010;
    --text: #fafafa;
    --soft: #d4d4d4;
    --muted: #8a8a8a;
    --hover: #e5e5e5;
    --line: #262626;
    --surface: #171616;
    --surface-hover: #1f1e1e;
    --tag: #232222;
    --link: #93c5fd;
    --field: #1a1919;
    --field-border: #333;
    --ok: #4ade80;
    --error: #f87171;
  }
}
:root[data-theme="dark"] {
  --bg: #111010;
  --text: #fafafa;
  --soft: #d4d4d4;
  --muted: #8a8a8a;
  --hover: #e5e5e5;
  --line: #262626;
  --surface: #171616;
  --surface-hover: #1f1e1e;
  --tag: #232222;
  --link: #93c5fd;
  --field: #1a1919;
  --field-border: #333;
  --ok: #4ade80;
  --error: #f87171;
}
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* Page-to-page navigation: only the nav underline slides; the page itself swaps instantly (a full-page
   cross-fade made quick clicks feel laggy). Browsers without support just switch pages. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }
/* The transition overlay catches clicks while it runs; let them through so rapid nav clicks all register. */
::view-transition { pointer-events: none; }
::view-transition-group(nav-mark) { animation-duration: .2s; animation-timing-function: cubic-bezier(.2, 0, 0, 1); }

*, *::before, *::after { box-sizing: border-box; }
html {
  min-width: 360px;
  overflow-x: clip;
  background: var(--bg);
  color: var(--text);
  font-family: Graphik, system-ui, sans-serif;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
body { margin: 2rem 0 8rem; overflow-x: clip; }
::selection { background: #47a3f3; color: #fefefe; }
p, h1, h2, h3, ul { margin: 0; }
a { color: inherit; text-decoration: none; }
img, canvas { display: block; max-width: 100%; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 2px; }

/* A flex column, like the original layout: vertical margins add up instead of collapsing. */
.page { margin: 1.5rem 1.5rem 0; display: flex; flex-direction: column; max-width: 64rem; }
@media (min-width: 768px) { .page { margin-inline: 8rem; } }

/* Nav */
.nav { display: flex; align-self: stretch; margin: 0 0 4rem -8px; letter-spacing: -0.025em; }
.nav a { font-size: 1.5rem; line-height: 2rem; color: var(--muted); transition: color .15s; }
.nav a:hover { color: var(--hover); }
.nav a[aria-current='page'] { color: var(--text); }
.nav span { position: relative; display: block; padding: .25rem .5rem; }
.nav a[aria-current='page'] span::after {
  content: '';
  position: absolute;
  left: .5rem; right: .5rem; top: 2.25rem;
  height: 3px;
  background: var(--nav-mark);
  view-transition-name: nav-mark;
}

.divider { height: 1px; background: var(--divider); margin: 2.5rem 0; border: 0; }
.page-title { font-size: 1.875rem; line-height: 2.25rem; font-weight: 400; }
@media (min-width: 768px) { .page-title { font-size: 3rem; line-height: 1; } }
.section-title { font-size: 1.5rem; line-height: 2rem; font-weight: 400; margin: 0 0 1.5rem; }
.section-note { color: var(--muted); margin: -1rem 0 1.5rem; }
.link { color: var(--link); text-underline-offset: 3px; }
.link:hover { text-decoration: underline; }

/* Home: hero. Portrait left; name + tagline top-right; blurb bottom-right (below everything on phones). */
.intro {
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: minmax(120px, 36%) 1fr; grid-template-rows: auto auto;
  grid-template-areas: "portrait text" "blurb blurb"; gap: 1.5rem;
}
.portrait { grid-area: portrait; position: relative; height: 15rem; }
.portrait img, .portrait canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
.intro-text { grid-area: text; position: relative; z-index: 1; align-self: start; }
.intro h1 { font-size: 2.25rem; line-height: 2.5rem; font-weight: 600; margin-bottom: 1rem; }
.tagline { font-size: 1.25rem; line-height: 1.75rem; color: var(--soft); max-width: 26ch; }
.tagline span { display: block; }
.tagline span + span { color: var(--muted); }
.blurb { grid-area: blurb; position: relative; z-index: 1; color: var(--soft); max-width: 46ch; }
/* A short slogan in the hero's bottom corner (the blurb's slot). */
.slogan { grid-area: blurb; position: relative; z-index: 1; width: fit-content; font-size: 1.125rem; color: var(--text); letter-spacing: -0.01em; }
@media (min-width: 768px) {
  .intro {
    grid-template-columns: minmax(120px, 33%) 1fr; grid-template-rows: 1fr auto;
    grid-template-areas: "portrait text" "portrait blurb"; column-gap: 5rem; row-gap: 2rem;
    min-height: max(34vh, 260px); /* grows with the text instead of letting it overflow */
  }
  .portrait { height: auto; min-height: 15rem; } /* stretches to the hero's height (grid stretch) */
  .blurb { max-width: 30rem; }
  .intro h1 { font-size: 3rem; line-height: 1; margin-bottom: 1.5rem; }
  .tagline { font-size: 1.75rem; line-height: 2.25rem; }
  .blurb, .slogan { align-self: end; }
}
@media (min-width: 1024px) { .intro h1 { font-size: 3.75rem; } }

/* Effects layers (fx/*.js). Hidden until a script draws, so nothing flashes or shifts.
   Canvases are replaced elements: insets alone don't size them, so width/height are explicit. */
.fx { position: absolute; max-width: none; pointer-events: none; opacity: 0; transition: opacity 1.2s ease; }
.fx.on { opacity: 1; }
/* The marlin: large and faint behind the whole hero (the portrait sits above it). Tablet width and up. */
.fx-hero { display: none; top: -3.5rem; left: -2rem; width: calc(100% + 10rem); height: calc(100% + 7rem); z-index: 0; }
@media (min-width: 768px) { .fx-hero { display: block; } }
.portrait { z-index: 1; }
.fx-topo { top: -6rem; left: -8rem; width: calc(100% + 16rem); height: calc(100% + 8rem); z-index: -1; }
.fx-portrait { inset: 0; width: 100%; height: 100%; }

/* Home: system diagram ("building now") */
.philosophy { max-width: 46rem; margin-bottom: 2rem; padding-left: 1rem; border-left: 2px solid var(--line); }
.philosophy p { color: var(--soft); font-size: 1.0625rem; line-height: 1.7; }
.more-work { margin-top: 2rem; }
.more-work a { color: var(--soft); text-decoration: underline; text-underline-offset: 4px; text-decoration-color: var(--divider); }
.more-work a:hover { color: var(--text); text-decoration-color: var(--text); }
.system { margin: 0; }
.system svg { width: 100%; height: auto; overflow: visible; }
.system .edges path { fill: none; stroke: var(--divider); stroke-width: 1.25; }
.system .edges path.planned { stroke-dasharray: 4 5; }
.system .pulses use { fill: none; stroke: var(--text); stroke-width: 2; stroke-linecap: round;
  stroke-dasharray: 6 400; stroke-dashoffset: 400; animation: pulse 4.5s linear infinite; animation-delay: var(--d); opacity: .55; }
@keyframes pulse { to { stroke-dashoffset: -10; } }
.system .node { cursor: default; outline: none; }
.system a.node { cursor: pointer; }
.system .node circle, .system .node rect { fill: var(--bg); stroke: var(--muted); stroke-width: 1.5; transition: stroke .15s, fill .15s; }
.system .node.hub circle { stroke: var(--text); stroke-width: 1.75; }
.system .node.planned circle { stroke-dasharray: 3 3; }
.system .node text { fill: var(--soft); font-size: 15px; text-anchor: middle; transition: fill .15s; }
.system .node.hub text { fill: var(--text); font-weight: 600; }
.system .node.right text { text-anchor: start; }
.system .node:hover circle, .system .node:hover rect, .system .node:focus-visible circle, .system .node:focus-visible rect,
.system .node.active circle, .system .node.active rect { stroke: var(--text); fill: var(--surface-hover); }
.system .node:hover text, .system .node:focus-visible text, .system .node.active text { fill: var(--text); }
.system .node:focus-visible circle, .system .node:focus-visible rect { stroke: var(--focus); }
.system-caption { min-height: 3rem; margin-top: 1rem; color: var(--soft); max-width: 46rem; }
.system-caption strong { color: var(--text); font-weight: 600; }
/* The zoomed-in Life Hub diagram on /projects: same language, with what's inside each piece. */
.system.deep { margin: .5rem 0 1rem; }
/* Wider than the text column, so its labels stay readable: the full page width, up to 64rem. */
@media (min-width: 640px) { .system.deep { width: calc(100vw - 3rem); max-width: none; } }
@media (min-width: 768px) { .system.deep { width: min(64rem, calc(100vw - 16rem)); } }
.system.deep text { fill: var(--soft); font-size: 13px; }
.system.deep text.c { text-anchor: middle; }
.system.deep text.title { fill: var(--text); font-size: 15px; font-weight: 600; }
.system.deep text.label { fill: var(--muted); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; }
.system.deep text.note { fill: var(--muted); font-size: 11.5px; }
.system.deep text.edge-label { fill: var(--muted); font-size: 11px; text-anchor: middle; }
.system.deep .box { fill: var(--surface); stroke: var(--line); stroke-width: 1.25; }
.system.deep .box.hub { stroke: var(--text); stroke-width: 1.5; }
.system.deep .rule { stroke: var(--line); }
.system.deep .node text { text-anchor: start; }
.system.deep .node text.c { text-anchor: middle; }
/* On narrow screens the diagram is too small to read: show the same content as a list instead. */
.system-list { list-style: none; padding: 0; margin: 0; display: grid; gap: .75rem; }
.system-list strong { display: block; font-weight: 600; }
.system-list a { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--divider); }
.system-list span { color: var(--soft); }
@media (min-width: 640px) { .system-list { display: none; } }
@media (max-width: 639px) { .system { display: none; } }
.cards.two { grid-template-columns: 1fr; }
@media (min-width: 768px) { .cards.two { grid-template-columns: repeat(2, 1fr); } }
.mini .tags { margin-top: auto; padding-top: .5rem; }

/* Footer sign-off: the small marlin variant (fx=marlin-footer). */
.sign-off { position: relative; height: 0; }
.fx-footer { left: auto; right: 0; bottom: -1.5rem; width: 220px; height: 150px; }

/* Home: now + toolbox */
.cards { display: grid; gap: 1rem; }
@media (min-width: 768px) { .cards { grid-template-columns: repeat(3, 1fr); } }
.mini {
  display: flex; flex-direction: column; gap: .5rem;
  padding: 1.25rem; border: 1px solid var(--line); border-radius: .5rem; background: var(--surface);
  transition: background .15s, border-color .15s;
}
a.mini:hover { background: var(--surface-hover); border-color: var(--divider); }
.mini h3 { font-size: 1.125rem; font-weight: 600; }
.mini p { color: var(--soft); font-size: .9375rem; }

.toolbox { display: grid; gap: .75rem 2rem; }
@media (min-width: 768px) { .toolbox { grid-template-columns: 9rem 1fr; } }
.toolbox dt { color: var(--muted); }
.toolbox dd { margin: 0 0 .5rem; }
@media (min-width: 768px) { .toolbox dd { margin: 0; } }

/* Tags */
.tags { display: flex; flex-wrap: wrap; gap: .375rem; list-style: none; padding: 0; margin: 0; }
.tags li { font-size: .8125rem; line-height: 1.5rem; padding: 0 .5rem; border-radius: .25rem; background: var(--tag); color: var(--soft); }

/* Projects */
/* Each project opens with a visible rule and a running number, so they read as separate entries while scrolling. */
main.page { counter-reset: project; }
.project { counter-increment: project; padding: 2rem 0 4rem; border-top: 1px solid var(--divider); scroll-margin-top: 1.5rem; }
.project::before { content: counter(project, decimal-leading-zero); display: block; margin-bottom: 1rem;
  font-size: .8125rem; letter-spacing: .08em; color: var(--muted); font-variant-numeric: tabular-nums; }
.section-title + .project, .section-note + .project { margin-top: .5rem; }
.project-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.project-head img { width: 3.5rem; height: 3.5rem; flex-shrink: 0; object-fit: contain; border-radius: .5rem; background: #fff; padding: .25rem; border: 1px solid var(--line); }
.project-head img.wide { width: 6rem; }
.project-head h2 { font-size: 1.75rem; line-height: 2.25rem; font-weight: 600; letter-spacing: -0.01em; }
@media (min-width: 768px) { .project-head h2 { font-size: 2rem; line-height: 2.5rem; } }
.project-head p { color: var(--muted); }
.project-head a:hover h2 { text-decoration: underline; text-underline-offset: 4px; }
.project-body { display: grid; gap: .75rem; grid-template-columns: minmax(0, 46rem); color: var(--soft); } /* text stays 46rem; wide figures may extend past it */
.project-body .tags { margin-top: .5rem; }
.project video { display: block; width: 100%; max-width: 40rem; aspect-ratio: 16 / 9; margin: .5rem 0 1rem; background: #000; border-radius: .5rem; }
.project .links { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: .25rem; }
.personal { display: grid; gap: 1rem; margin-bottom: 1rem; }
@media (min-width: 768px) { .personal { grid-template-columns: repeat(3, 1fr); } }
.personal .mini h3 { font-size: 1.25rem; }

/* Projects: screenshots and diagrams */
.shots { display: flex; gap: 1rem; flex-wrap: wrap; margin: .5rem 0; }
.shots figure { margin: 0; width: min(15rem, calc(50% - .5rem)); }
.shots img { width: 100%; height: auto; border-radius: 1rem; border: 1px solid var(--line); background: var(--surface); }
/* One wide image across the project's width. */
.hero-shot { margin: .5rem 0; max-width: 46rem; }
.hero-shot img { width: 100%; height: auto; border-radius: .75rem; border: 1px solid var(--line); }
/* Four phone screenshots in a row (two by two on phones). */
.shots.four figure { width: calc(50% - .5rem); }
@media (min-width: 768px) { .shots.four { flex-wrap: nowrap; } .shots.four figure { width: calc(25% - .75rem); } }
.shots.four img { border-radius: .75rem; }
.shots-caption { font-size: .8125rem; color: var(--muted); margin-top: -.25rem; }
/* Landscape screenshots (the sandbox): two across on wide screens, stacked on phones. */
.shots.wide figure { width: 100%; }
@media (min-width: 768px) { .shots.wide { flex-wrap: nowrap; } .shots.wide figure { width: calc(50% - .5rem); } }
.shots.wide img { border-radius: .75rem; }
.shots figcaption { font-size: .8125rem; color: var(--muted); margin-top: .5rem; }
.stack { display: grid; gap: 0; margin: .5rem 0; max-width: 40rem; }
@media (min-width: 768px) { .stack { grid-template-columns: 1fr 2rem 1fr 2rem 1fr; align-items: stretch; } }
.tier { display: flex; flex-direction: column; gap: .125rem; border: 1px solid var(--line); border-radius: .5rem; background: var(--surface); padding: .875rem 1rem; }
.tier-name { font-size: .75rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.tier strong { font-weight: 600; color: var(--text); }
.tier span:last-child { color: var(--soft); font-size: .875rem; }
.stack .link { height: 1.25rem; width: 1px; background: var(--divider); justify-self: center; }
@media (min-width: 768px) { .stack .link { height: 1px; width: 100%; align-self: center; } }

/* Contact */
.contact { display: grid; gap: 2.5rem; align-items: start; }
@media (min-width: 768px) { .contact { grid-template-columns: 1fr 1.4fr; gap: 4rem; } }
.contact-intro p { color: var(--soft); margin-bottom: 1.5rem; max-width: 34ch; }
.socials { display: flex; flex-direction: column; gap: .75rem; list-style: none; padding: 0; margin: 0; }
.socials a { display: inline-flex; align-items: center; gap: .75rem; color: var(--text); }
.socials a:hover span { text-decoration: underline; text-underline-offset: 4px; }
.socials svg { width: 1.25rem; height: 1.25rem; fill: currentColor; }
.form-title { font-size: 1.25rem; line-height: 1.75rem; font-weight: 600; margin-bottom: 1rem; }
form { position: relative; display: flex; flex-direction: column; }
form label { display: block; font-size: .9375rem; margin-bottom: .25rem; }
form input, form textarea {
  font: inherit;
  margin: 0 0 1rem;
  padding: .625rem .75rem;
  border: 1px solid var(--field-border);
  border-radius: .375rem;
  background: var(--field);
  color: var(--text);
  -webkit-appearance: none;
  appearance: none;
  transition: border-color .15s;
}
form input::placeholder, form textarea::placeholder { color: var(--muted); }
form input:hover, form textarea:hover { border-color: var(--divider); }
form input:focus, form textarea:focus { outline: 2px solid var(--focus); outline-offset: 0; border-color: transparent; }
form textarea { min-height: 7rem; resize: vertical; }
form button {
  font: inherit;
  align-self: flex-start;
  margin-top: .5rem;
  padding: .625rem 1.5rem;
  border: 0;
  border-radius: .375rem;
  background: var(--text);
  color: var(--bg);
  cursor: pointer;
  transition: opacity .15s;
}
form button:hover { opacity: .85; }
form button:disabled { cursor: progress; opacity: .6; }
.form-status { min-height: 1.5rem; margin-top: 1rem; }
.form-status.ok { color: var(--ok); }
.form-status.error { color: var(--error); }

/* Footer */
.footer { margin-top: 5rem; padding-top: 1.5rem; border-top: 1px solid var(--line); color: var(--muted); font-size: .875rem; display: flex; justify-content: space-between; flex-wrap: wrap; gap: .5rem; }
.footer a:hover { color: var(--text); }
/* Theme toggle: a small icon at the right end of the nav (auto ◐ / light ☀ / dark ☾). */
.theme-toggle { margin-left: auto; align-self: center; display: grid; place-items: center; width: 2rem; height: 2rem;
  color: var(--muted); background: none; border: 0; border-radius: 999px; padding: 0; cursor: pointer; opacity: .7;
  transition: color .15s, opacity .15s; }
.theme-toggle:hover, .theme-toggle:focus-visible { color: var(--text); opacity: 1; }
.theme-toggle svg { width: 1.125rem; height: 1.125rem; display: none; }
:root:not([data-theme]) .theme-toggle .i-auto, :root[data-theme="light"] .theme-toggle .i-light,
:root[data-theme="dark"] .theme-toggle .i-dark { display: block; }

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