/* ==========================================================================
   Andrew Martino — personal site

   The visual language is cartographic: a contour field on a deep slate
   ground, sage-teal lines, and a single warm ochre accent reserved for
   things you can actually click. The page commits to one dark treatment
   rather than following the viewer's theme, so every colour is painted
   explicitly and nothing is inherited from the host.
   ========================================================================== */

:root {
    /* Ground and surfaces. The neutrals carry a slight teal bias so they
       sit with the contour lines instead of reading as flat grey. */
    --ink: #0c1317;
    --ink-raised: #121d22;
    --ink-hover: #16242a;
    --rule: rgba(233, 239, 241, 0.11);
    --rule-strong: rgba(233, 239, 241, 0.2);

    /* Text */
    --paper: #e9eff1;
    --paper-dim: rgba(233, 239, 241, 0.66);
    --paper-faint: rgba(233, 239, 241, 0.42);

    /* The two hues: cool for the map, warm for interaction. */
    --contour: #6fb5a4;
    --accent: #d99a5b;
    --accent-bright: #eab077;
    --accent-ink: #21150a;

    --font-display: "Bricolage Grotesque", "Archivo", system-ui, sans-serif;
    --font-body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Consolas, monospace;

    --measure: 64ch;
    --shell: 1040px;
    --radius: 14px;
}

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

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

body {
    min-height: 100vh;
    /* The canvas sits behind everything, so the body still paints the ground
       for the moment before the first frame lands. */
    background: var(--ink);
    color: var(--paper);
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.6;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

#backdrop {
    position: fixed;
    inset: 0;
    z-index: -1;
    display: block;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

a {
    color: var(--accent);
    text-decoration-color: rgba(217, 154, 91, 0.4);
    text-underline-offset: 0.18em;
}

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

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

.skip-link {
    position: absolute;
    left: 12px;
    top: -60px;
    z-index: 20;
    padding: 10px 16px;
    border-radius: 8px;
    background: var(--accent);
    color: var(--accent-ink);
    font-weight: 600;
    text-decoration: none;
    transition: top 0.18s ease;
}

.skip-link:focus {
    top: 12px;
    color: var(--accent-ink);
}

/* --------------------------------------------------------------------------
   Shell
   -------------------------------------------------------------------------- */

.page-shell {
    width: min(100%, var(--shell));
    min-height: 100vh;
    margin: 0 auto;
    padding: 28px 24px 40px;
    display: flex;
    flex-direction: column;
    gap: 64px;
}

/* main is the only place two big blocks stack, so it owns that rhythm. */
main {
    display: flex;
    flex-direction: column;
    gap: 64px;
}

.site-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.nav-mark {
    font-family: var(--font-mono);
    font-size: 0.76rem;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--paper-dim);
    text-decoration: none;
}

.nav-mark:hover {
    color: var(--paper);
}

.eyebrow {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--contour);
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding-top: 32px;
}

.site-title {
    font-family: var(--font-display);
    font-size: clamp(2.6rem, 8vw, 4.6rem);
    font-weight: 700;
    line-height: 1.02;
    letter-spacing: -0.02em;
    text-wrap: balance;
}

.hero-lede {
    max-width: var(--measure);
    color: var(--paper-dim);
    font-size: clamp(1.02rem, 2.2vw, 1.18rem);
    line-height: 1.65;
}

.hero-lede strong {
    color: var(--paper);
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   Sections
   -------------------------------------------------------------------------- */

.section {
    display: flex;
    flex-direction: column;
    gap: 22px;
}

.section-head {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--rule);
}

.section-head h2 {
    font-family: var(--font-display);
    font-size: 1.4rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* --------------------------------------------------------------------------
   Project tiles

   Two roles, two treatments: the project tiles are the substance of the page
   and get artwork, a status chip and a description; the GitHub tile is a
   utility link and stays deliberately slim so it doesn't compete.
   -------------------------------------------------------------------------- */

.project-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 20px;
}

.tile {
    position: relative;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: rgba(18, 29, 34, 0.82);
    backdrop-filter: blur(9px);
    -webkit-backdrop-filter: blur(9px);
    color: inherit;
    text-decoration: none;
    overflow: hidden;
    transition: border-color 0.2s ease, transform 0.2s ease, background-color 0.2s ease;
}

.tile:hover,
.tile:focus-visible {
    border-color: var(--rule-strong);
    background: rgba(22, 36, 42, 0.9);
    transform: translateY(-3px);
    color: inherit;
}

.tile-art {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 2 / 1;
    border-bottom: 1px solid var(--rule);
    background: rgba(9, 16, 19, 0.6);
}

.tile-body {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 22px 22px 24px;
    flex: 1;
}

.tile-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.tile-title {
    font-family: var(--font-display);
    font-size: 1.32rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--paper);
}

.tile-body p {
    color: var(--paper-dim);
    font-size: 0.95rem;
    line-height: 1.6;
}

/* Status is state, so it reads as a chip rather than as another line of prose. */
.chip {
    flex: none;
    padding: 4px 10px;
    border: 1px solid;
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: 0.63rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
}

.chip-live {
    border-color: rgba(111, 181, 164, 0.45);
    background: rgba(111, 181, 164, 0.13);
    color: var(--contour);
}

.chip-build {
    border-color: rgba(217, 154, 91, 0.45);
    background: rgba(217, 154, 91, 0.12);
    color: var(--accent);
}

.tile-action {
    margin-top: auto;
    padding-top: 14px;
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--accent);
}

.tile-action .arrow {
    transition: transform 0.2s ease;
}

.tile:hover .tile-action .arrow,
.tile:focus-visible .tile-action .arrow {
    transform: translateX(4px);
}

/* The utility tile: same family, different weight in the hierarchy. */
.link-tile {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 18px 22px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: rgba(18, 29, 34, 0.72);
    backdrop-filter: blur(9px);
    -webkit-backdrop-filter: blur(9px);
    color: inherit;
    text-decoration: none;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.link-tile:hover,
.link-tile:focus-visible {
    border-color: var(--rule-strong);
    background: rgba(22, 36, 42, 0.85);
    color: inherit;
}

.link-tile svg {
    flex: none;
    color: var(--paper-dim);
}

.link-tile:hover svg {
    color: var(--paper);
}

.link-tile-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.link-tile-text strong {
    font-family: var(--font-display);
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--paper);
}

.link-tile-text span {
    color: var(--paper-faint);
    font-family: var(--font-mono);
    font-size: 0.74rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.link-tile .arrow {
    margin-left: auto;
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 0.8rem;
    transition: transform 0.2s ease;
}

.link-tile:hover .arrow {
    transform: translateX(4px);
}

/* --------------------------------------------------------------------------
   Creed

   The quote closes the page rather than opening it: the projects make the
   argument and this names it. The mark above it is a summit drawn as contour
   rings, so it belongs to the same map language as the backdrop.
   -------------------------------------------------------------------------- */

.creed {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 22px;
    padding: 60px 0;
    text-align: center;
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
}

.creed-mark {
    width: 104px;
    height: auto;
}

.creed blockquote {
    max-width: 24ch;
    font-family: var(--font-display);
    font-size: clamp(1.7rem, 4.2vw, 2.5rem);
    font-weight: 600;
    line-height: 1.16;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

/* The second clause is the turn the whole line exists for. */
.creed .turn {
    display: block;
    color: var(--accent);
}

.creed cite {
    font-style: normal;
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--paper-faint);
}

/* --------------------------------------------------------------------------
   Article — the project detail page
   -------------------------------------------------------------------------- */

.article {
    display: flex;
    flex-direction: column;
    gap: 40px;
}

.article-head {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.article-title {
    font-family: var(--font-display);
    font-size: clamp(2.1rem, 6vw, 3.4rem);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.02em;
    text-wrap: balance;
}

.article-lede {
    max-width: var(--measure);
    color: var(--paper-dim);
    font-size: clamp(1.04rem, 2.2vw, 1.2rem);
    line-height: 1.62;
}

.article-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
}

.prose {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: var(--measure);
}

.prose p {
    color: var(--paper-dim);
    line-height: 1.72;
}

.prose strong {
    color: var(--paper);
    font-weight: 600;
}

.prose code {
    padding: 1px 6px;
    border: 1px solid var(--rule);
    border-radius: 5px;
    background: rgba(9, 16, 19, 0.7);
    font-family: var(--font-mono);
    font-size: 0.86em;
    color: var(--contour);
}

/* A definition list beats bullets for "term — what it means" pairs. */
.spec-list {
    display: grid;
    grid-template-columns: minmax(140px, 200px) 1fr;
    gap: 2px 28px;
    max-width: 760px;
}

.spec-list dt {
    padding: 12px 0;
    border-top: 1px solid var(--rule);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--contour);
}

.spec-list dd {
    padding: 12px 0;
    border-top: 1px solid var(--rule);
    color: var(--paper-dim);
}

.figure {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 24px 22px 20px;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: rgba(18, 29, 34, 0.72);
    backdrop-filter: blur(9px);
    -webkit-backdrop-filter: blur(9px);
}

/* A wide diagram scrolls inside its own box; the page body never does. */
.figure-scroll {
    overflow-x: auto;
    padding-bottom: 4px;
}

.figure-scroll svg {
    display: block;
    min-width: 540px;
    width: 100%;
    height: auto;
}

.figure figcaption {
    color: var(--paper-faint);
    font-size: 0.84rem;
    line-height: 1.6;
}

.back-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 0.74rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--paper-dim);
}

.back-link:hover {
    color: var(--accent);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
    margin-top: auto;
    padding-top: 24px;
    border-top: 1px solid var(--rule);
    display: flex;
    flex-wrap: wrap;
    gap: 10px 20px;
    align-items: center;
    justify-content: space-between;
    color: var(--paper-faint);
    font-family: var(--font-mono);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
}

/* --------------------------------------------------------------------------
   Tile artwork — shared drawing language with the contour backdrop
   -------------------------------------------------------------------------- */

.art-contour { stroke: var(--contour); fill: none; opacity: 0.3; }
.art-contour-strong { stroke: var(--contour); fill: none; opacity: 0.55; }
.art-structure { stroke: var(--paper); fill: none; opacity: 0.5; }
.art-fill-cool { fill: var(--contour); opacity: 0.14; }
.art-fill-warm { fill: var(--accent); opacity: 0.16; }
.art-warm { stroke: var(--accent); fill: none; }
.art-warm-solid { fill: var(--accent); }
.art-cool-solid { fill: var(--contour); }
.art-ink { fill: var(--ink); }

/* --------------------------------------------------------------------------
   Diagram
   -------------------------------------------------------------------------- */

.dg-box {
    fill: rgba(18, 29, 34, 0.92);
    stroke: var(--rule-strong);
    stroke-width: 1;
}

.dg-label {
    fill: var(--paper);
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
}

.dg-sub {
    fill: var(--paper-faint);
    font-family: var(--font-mono);
    font-size: 10px;
}

.dg-edge {
    fill: var(--paper-dim);
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.05em;
}

.dg-edge-warm { fill: var(--accent); }

.dg-flow { stroke: var(--contour); fill: none; stroke-width: 1.4; }
.dg-bytes { stroke: var(--accent); fill: none; stroke-width: 3.4; }
.dg-machine { stroke: var(--rule-strong); fill: none; stroke-width: 1; stroke-dasharray: 5 5; }
.dg-head-cool { fill: var(--contour); }
.dg-head-warm { fill: var(--accent); }

/* --------------------------------------------------------------------------
   Narrow viewports
   -------------------------------------------------------------------------- */

@media (max-width: 640px) {
    .page-shell {
        padding: 20px 16px 32px;
        gap: 48px;
    }

    .hero {
        padding-top: 12px;
    }

    .spec-list {
        grid-template-columns: 1fr;
        gap: 0;
    }

    .spec-list dd {
        border-top: 0;
        padding-top: 0;
        padding-bottom: 16px;
    }

    .tile-body {
        padding: 18px 18px 20px;
    }

    .creed {
        padding: 44px 0;
        gap: 18px;
    }

    .creed-mark {
        width: 70px;
    }

    .figure {
        padding: 18px 16px 16px;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
