/* Fonts are hosted on this server (fonts/, SIL Open Font License, see the OFL-*.txt files there),
   so no visitor data goes to Google. Latin + Latin Extended subsets only. */
@font-face {
    font-family: 'Jersey 10';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/jersey-10-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Jersey 10';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/jersey-10-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  color-scheme: dark;

  /* ---------- Colors: dark (the default) ---------- */
  --color-background: #0f1117;   /* body: the gutters beside the page on wide screens */
  --color-page: #282C33;         /* the page and the nav */
  --color-primary: #FFFFFF;      /* text */
  --color-secondary: #9C9C9C;    /* quieter text, inactive nav links */
  --color-accent: #EE5959;
  --color-border: #0D99FF;       /* the one bright colour: buttons, headings on the résumé, active tab marker */

  /* Panels that sit on the page (project cards, the console) */
  --color-card: #1B1F26;         /* panel body: deeper than the page */
  --color-card-bar: #30353E;     /* panel title bar: lifted above the page */
  --color-line: #3A3F48;         /* panel borders and dividers */
  --color-text-soft: #C8CBD1;    /* running text on panels: brighter than secondary, quieter than white */
  --color-screen: #0f1117;       /* frame around screenshots */
  --color-live: #4CD964;         /* "runs in your browser" */

  --color-shadow: #0f1117;                        /* hard pixel shadows */
  --shadow-soft: 0 4px 12px rgba(0, 0, 0, 0.4);   /* nav bar, photos, floating buttons */
  --shadow-soft-up: 0 -4px 12px rgba(0, 0, 0, 0.4); /* the tab bar at the bottom */
  --icon-filter: none;                            /* nav icons (drawn in --color-secondary grey) */
  --icon-filter-active: brightness(0) invert(1);  /* the active one: white */

  /* Font */
  --font-primary: 'Jersey 10', monospace;

  /* Layout */
  --page-width: 1440px;           /* the page never grows wider than this */
  --nav-height: 60px;
  --gutter: clamp(16px, 4vw, 40px); /* side padding of page content: 16px on phones, 40px on desktops */
  --bottom-bar: 0px;                /* height of the bottom nav bar on phones (0 while the bar is at the top) */
}

/* ---------- Colors: light ----------
   Used when the visitor's system is set to light and they have not chosen otherwise on the site,
   or when they switched to light with the sun/moon button (data-theme, set by theme.js).
   Same roles as above; the blue and red are a step darker so text in them stays readable on light. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --color-background: #D3D7DE;
    --color-page: #F2F3F6;
    --color-primary: #15171C;
    --color-secondary: #666C77;
    --color-accent: #D23C3C;
    --color-border: #0A6FBF;
    --color-card: #FFFFFF;
    --color-card-bar: #E4E7EC;
    --color-line: #C6CBD3;
    --color-text-soft: #3A3F4A;
    --color-screen: #E1E4EA;
    --color-live: #1F9A3D;
    --color-shadow: #B7BDC7;
    --shadow-soft: 0 4px 12px rgba(20, 24, 32, 0.14);
    --shadow-soft-up: 0 -4px 12px rgba(20, 24, 32, 0.14);
    --icon-filter: brightness(0.68);
    --icon-filter-active: brightness(0);
  }
}

:root[data-theme="light"] {
  color-scheme: light;
  --color-background: #D3D7DE;
  --color-page: #F2F3F6;
  --color-primary: #15171C;
  --color-secondary: #666C77;
  --color-accent: #D23C3C;
  --color-border: #0A6FBF;
  --color-card: #FFFFFF;
  --color-card-bar: #E4E7EC;
  --color-line: #C6CBD3;
  --color-text-soft: #3A3F4A;
  --color-screen: #E1E4EA;
  --color-live: #1F9A3D;
  --color-shadow: #B7BDC7;
  --shadow-soft: 0 4px 12px rgba(20, 24, 32, 0.14);
  --shadow-soft-up: 0 -4px 12px rgba(20, 24, 32, 0.14);
  --icon-filter: brightness(0.68);
  --icon-filter-active: brightness(0);
}

/* Short landscape screens (phones held sideways): a slimmer bar leaves more room for the page */
@media screen and (max-height: 500px) {
  :root {
    --nav-height: 48px;
  }
}

html {
    overscroll-behavior: none;
    /* iOS Safari inflates text in landscape without this */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    /* In-page anchors are not hidden under the fixed nav */
    scroll-padding-top: var(--nav-height);
}

body {
  margin: 0;
  background-color: var(--color-background);
  color: var(--color-primary);
  font-family: var(--font-primary);
}

img {
  max-width: 100%;   /* an image is never wider than its container */
  height: auto;
  user-select: none;
  -webkit-user-drag: none;
}

/* ---------- Navigation ---------- */
nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    width: 100%;
    max-width: var(--page-width);
    height: var(--nav-height);
    margin: 0 auto;
    padding: 0 clamp(12px, 2vw, 20px);
    box-sizing: border-box;
    z-index: 10;
    background-color: var(--color-page);
    border-radius: 0 0 12px 12px;
    box-shadow: var(--shadow-soft);
}

.home_button {
    display: flex;
    align-items: center;
    justify-content: center;
}

.home_button a {
    display: flex;
    align-items: center;
    min-height: 44px;  /* comfortable tap target */
    padding: 0 4px;
}

/* 13 x 11 px pixel art (same house as in the phone tab bar), drawn at 3px per pixel */
.home_button img {
    width: 39px;
    height: 33px;
    image-rendering: pixelated;
}

.home_button img {
    filter: var(--icon-filter);
}

/* On the homepage: same colour as the active nav link */
.home_button a.active img {
    filter: var(--icon-filter-active);
}

.page_selection {
    display: flex;
    gap: clamp(16px, 3.5vw, 48px);
    margin-left: auto;  /* links sit at the right end, the house stays left */
}

.page_selection a {
    display: flex;
    align-items: center;
    min-height: 44px;  /* comfortable tap target */
    font-family: var(--font-primary);
    font-size: clamp(24px, 2.4vw, 30px);
    color: var(--color-secondary);
    text-decoration: none;
    white-space: nowrap;
}

.page_selection a.active {
    color: var(--color-primary);
    text-shadow: 0 0 0.5px currentColor, 0 0 0.5px currentColor;
}

/* Desktop: the house is the only icon, the pages are text links. (The pixel icons and the "Home" label
   belong to the phone tab bar below.) */
.home_button span,
.page_selection img {
    display: none;
}

/* Light / dark switch: a pixel sun or moon after the links (see theme.js) */
.theme_toggle[hidden] {
    display: none;  /* until theme.js has run: without it there is nothing to switch */
}

.theme_toggle {
    display: grid;
    place-items: center;
    flex: none;
    width: 44px;
    height: 44px;
    margin-left: clamp(12px, 2.5vw, 32px);
    padding: 0 0 0 clamp(10px, 1.5vw, 16px);
    border: 0;
    border-left: 2px solid var(--color-line);
    border-radius: 0;
    background: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.theme_toggle img {
    display: block;
    width: 26px;
    height: 22px;
    image-rendering: pixelated;
    filter: var(--icon-filter);
}

.theme_toggle:focus-visible {
    outline: 2px solid var(--color-border);
    outline-offset: 2px;
}

@media (hover: hover) {
    .theme_toggle:hover img {
        filter: var(--icon-filter-active);
    }
}

/* ---------- Phones: tab bar at the bottom, within thumb reach ----------
   One pixel icon + label per page, like an app. --bottom-bar tells the pages how much room to leave. */
@media screen and (max-width: 760px) {
    :root {
        --bottom-bar: var(--nav-height);
    }

    /* No env(safe-area-inset-bottom) here on purpose: the page does not use viewport-fit=cover, so the browser already
       keeps it clear of the system bars. Firefox on Android reports the Android navigation bar's height anyway,
       which made the tab bar twice as tall there (icons on top, empty space below). */
    nav {
        height: var(--bottom-bar);
        padding: 0 4px;
        border-top: 2px solid var(--color-line);
        border-radius: 12px 12px 0 0;
        box-shadow: var(--shadow-soft-up);
    }

    /* The two groups dissolve, so all six tabs share the width evenly */
    .home_button,
    .page_selection {
        display: contents;
    }

    .home_button a,
    .page_selection a {
        position: relative;
        flex: 1 1 0;
        align-self: stretch;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 5px;
        min-width: 0;
        min-height: 0;
        padding: 0;
        color: var(--color-secondary);
        font-size: 15px;
        line-height: 1;
        text-decoration: none;
        white-space: nowrap;
        -webkit-tap-highlight-color: transparent;
    }

    /* 13 x 11 px pixel art, drawn at 2px per pixel */
    .home_button img,
    .page_selection img {
        display: block;
        width: 26px;
        height: 22px;
        margin: 0;
        image-rendering: pixelated;
        filter: var(--icon-filter);
    }

    .home_button span,
    .page_selection span {
        display: block;
        overflow: hidden;
        max-width: 100%;
        text-overflow: ellipsis;
    }

    /* "Contact Me" becomes "Contact" in the bar: short labels, as in apps */
    .page_selection .wide {
        display: none;
    }

    .home_button a.active,
    .page_selection a.active {
        color: var(--color-primary);
    }

    .home_button a.active img,
    .page_selection a.active img {
        filter: var(--icon-filter-active);
    }

    /* Pixel marker on the top edge of the current tab */
    .home_button a.active::before,
    .page_selection a.active::before {
        content: "";
        position: absolute;
        top: -2px;
        left: 50%;
        width: 26px;
        height: 4px;
        translate: -50% 0;
        background-color: var(--color-border);
    }

}

/* Phones held sideways: the bar is only 48px but wide, so the label sits next to the icon */
@media screen and (max-width: 760px) and (max-height: 500px) {
    .home_button a,
    .page_selection a {
        flex-direction: row;
        gap: 8px;
    }
}

/* ---------- Page ---------- */
main {
    width: 100%;
    max-width: var(--page-width);
    /* svh = the screen with the browser's address bar visible. Unlike vh/dvh it never changes while the
       address bar slides away, so the page does not re-flow (and the tab bar does not jump) while scrolling,
       and short pages are not scrollable by the bar's height (Firefox on Android) */
    min-height: 100vh;
    min-height: 100svh;
    margin: 0 auto;
    padding-top: var(--nav-height);
    box-sizing: border-box;
    background-color: var(--color-page);
}

/* Phones: the document itself does not scroll, the page scrolls inside <main> and the tab bar sits below it in
   normal flow (not position: fixed). Reason: Firefox on Android collapses its address bar only when the document
   scrolls, and each time it does so it re-anchors fixed elements with a visible jump. With the document pinned to
   the screen height the address bar stays, and the tab bar never moves - in every browser.
   This block comes after the main rule above on purpose: same specificity, the later rule wins. */
@media screen and (max-width: 760px) {
    html,
    body {
        height: 100%;
        overflow: hidden;
    }

    body {
        display: flex;
        flex-direction: column;
        /* Same colour as the page: the tab bar's rounded top corners sit on the body, and on phones the
           page fills the whole width anyway (the darker body colour is only the desktop's side gutters) */
        background-color: var(--color-page);
    }

    main {
        flex: 1 1 auto;
        min-height: 0;
        padding-top: 56px;  /* the row the light/dark switch floats in, so it never covers the first thing on a page */
        padding-bottom: 0;
        overflow-y: auto;
        overscroll-behavior-y: contain;
    }

    /* Light / dark switch: a small pixel button in the top right corner, above the page.
       position: fixed is safe here because the document itself never scrolls on phones. */
    .theme_toggle {
        position: fixed;
        top: 8px;
        right: 12px;
        z-index: 5;
        width: 44px;
        height: 44px;
        margin: 0;
        padding: 0;
        border: 2px solid var(--color-line);
        border-radius: 8px;
        background-color: var(--color-page);
        box-shadow: 3px 3px 0 var(--color-shadow);
        transition: translate 0.12s steps(2), box-shadow 0.12s steps(2);
    }

    .theme_toggle:active {
        translate: 2px 2px;
        box-shadow: 1px 1px 0 var(--color-shadow);
    }

    nav {
        position: static;
        order: 2;
        flex: none;
    }
}

/* No animated transitions for visitors who turned animations off in their system settings */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}

/* ---------- Page switches ---------- */
/* Cross-fade between pages instead of a blank flash (Chrome, Edge, Safari 18.2+; other browsers switch as before).
   The nav bar has its own name, so it stays in place while only the page content fades. */
@view-transition {
    navigation: auto;
}

nav {
    view-transition-name: site-nav;
}

::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 150ms;
}

@media (prefers-reduced-motion: reduce) {
    @view-transition {
        navigation: none;
    }
}
