/* ===============================================================
   geo.css
   Shared layout for the JSXGraph geomap documentation pages.
   =============================================================== */

/* ---------------------------------------------------------------
   Design tokens
   --------------------------------------------------------------- */
:root {
    --bg:          #eef2f6;
    --surface:     #ffffff;
    --surface-2:   #f4f7fa;
    --code-bg:     #0e2739;
    --code-fg:     #cfe1ef;
    --text:        #16222e;
    --muted:       #5a7285;
    --border:      #dae3ea;
    --accent:      #2a5c7d;
    --accent-soft: #e2edf4;
    --gold:        #cf9b3f;

    --radius:   14px;
    --radius-s: 8px;
    --shadow: 0 1px 2px rgba(16, 38, 56, .06), 0 10px 28px rgba(16, 38, 56, .07);
    --nav-h: 3.25rem;

    /* The top bar. --lime-ink is the one colour the logo is drawn in, so the
       mark, the links and the rule are all the same blue; --lime-dim is a
       lighter shade of it for the group labels. Measured against the lime:
       6.55 for the ink, 3.23 for the dim. */
    --lime:      #cddc39;
    --lime-ink:  #12437c;
    --lime-dim:  #4c749f;

    --font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg:          #0b1219;
        --surface:     #121e28;
        --surface-2:   #17252f;
        --code-bg:     #0a1621;
        --code-fg:     #bcd4e6;
        --text:        #e7eff5;
        --muted:       #9ab0c0;
        --border:      #24384a;
        --accent:      #7fc0e8;
        --accent-soft: #16303f;
        --shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 10px 28px rgba(0, 0, 0, .35);

        /* --lime and its two inks are deliberately not redefined here. The
           logo is a single-colour SVG that carries #12437c whatever the
           scheme, so a dark top bar would put dark blue on dark. The bar
           stays light in both, which also keeps it the one fixed landmark on
           the page. */
    }
}

* { box-sizing: border-box; }

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

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * { animation: none !important; transition: none !important; }
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

.wrap {
    width: min(72rem, 100% - 2rem);
    margin-inline: auto;
}

/* ---------------------------------------------------------------
   Hero
   --------------------------------------------------------------- */
.hero {
    background:
        radial-gradient(1200px 380px at 15% -10%, rgba(207, 155, 63, .22), transparent 60%),
        linear-gradient(160deg, #0e2739 0%, #17384f 55%, #1d4a68 100%);
    color: #eaf3f9;
    padding: clamp(2.5rem, 7vw, 4.5rem) 0 clamp(2rem, 5vw, 3.25rem);
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.hero h1 {
    margin: 0 0 .6rem;
    font-size: clamp(1.9rem, 5.2vw, 3rem);
    line-height: 1.12;
    letter-spacing: -.02em;
    font-weight: 700;
}

.hero p {
    margin: 0 0 .8rem;
    xmax-width: 62ch;
    color: #b9d0e0;
    font-size: clamp(.95rem, 2.2vw, 1.05rem);
}

.hero code {
    background: rgba(255, 255, 255, .09);
    border-radius: 4px;
    padding: .1em .4em;
    font-family: var(--mono);
    font-size: .9em;
}

.hero a {
    color: var(--lime)
}

.hero__note {
    margin-top: 1.5rem;
    font-size: .82rem;
    color: #8fb0c6;
    border-left: 2px solid rgba(255, 255, 255, .18);
    padding-left: .85rem;
}

/* ---------------------------------------------------------------
   Sticky navigation
   --------------------------------------------------------------- */
/* No sticky of its own any more: it rides in .stickybar with the top bar.
   Solid rather than translucent now, because the two are stacked and a blur
   over a blur reads as neither. */
.nav {
    position: sticky;
    top: var(--topbar-h, 0px);
    z-index: 40;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
}

.nav__inner {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem .4rem;
    align-items: center;
    min-height: var(--nav-h);
    padding-block: .45rem;
}

.nav a {
    flex: 0 0 auto;
    color: var(--muted);
    text-decoration: none;
    font-size: .85rem;
    font-weight: 500;
    padding: .35rem .7rem;
    border-radius: 999px;
    white-space: nowrap;
    transition: background .15s, color .15s;
}

.nav a:hover,
.nav a:focus-visible {
    color: var(--accent);
    background: var(--accent-soft);
}

/* Every entry is visible. Twelve section links carry 157 characters and
   need roughly 1400 pixels in a single row — more than a laptop at 1280
   has — so the row wraps instead of scrolling. A hidden scrollbar left
   the far entries out of reach in practice, and a fade at the edge only
   made the cut look deliberate.

   The bar is sticky, so its height is what pushes the page down. Counted
   at 0.85rem: two rows above 1024px, three at 768, five at 390 — and a
   sticky bar 164 pixels tall eats half a phone screen. Below 60rem it
   therefore scrolls away with the page instead of staying put. */

@media (max-width: 60rem) {
    .nav { position: static; }
}

.nav a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* ---------------------------------------------------------------
   Sections
   --------------------------------------------------------------- */
main { padding: clamp(1.75rem, 5vw, 3rem) 0 4rem; }

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: clamp(1.1rem, 3.5vw, 1.9rem);
    margin-bottom: clamp(1.25rem, 3.5vw, 2rem);
    /* Clears both sticky bars, whose height together depends on how many rows
       each has wrapped to. Measured: 118 px above 1120, 174 px at 1024, 204
       at 768 — the value is stepped at the same breakpoints below. */
    scroll-margin-top: 8rem;
}

/* The two bars stack into more rows as the window narrows, so a jump target
   has to clear more of them. Below 46rem they no longer stick, and a small
   margin is enough. */
@media (max-width: 70rem) {
    .card { scroll-margin-top: 11.5rem; }
}

@media (max-width: 48rem) {
    .card { scroll-margin-top: 13.5rem; }
}

@media (max-width: 46rem) {
    .card { scroll-margin-top: 1.5rem; }
}

.card--featured {
    border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}

.card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .65rem;
    margin-bottom: .5rem;
}

/* The same lime and the same blue as the top bar, so the tag reads as part of
   the site's furniture rather than as one more accent colour. Contrast 6.55,
   measured. */
.badge {
    display: inline-block;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--lime-ink);
    background: var(--lime);
    border-radius: 999px;
    padding: .25rem .65rem;
}

/* The heading sits under the tag rather than beside it: an example title runs
   to forty characters, and beside a tag it wrapped into a ragged second line
   that started under the tag anyway.

   Done by turning the row into a column and using the flex `gap`, not by a
   margin on the heading. A margin there has to win against `.card h2 {
   margin: 0 }` on specificity and survive margin collapsing; the gap belongs
   to the container and neither question arises. */
.card__head--stacked {
    flex-direction: column;
    align-items: flex-start;
    gap: 1.5rem;
}

.card h2 {
    margin: 0;
    font-size: clamp(1.15rem, 3vw, 1.45rem);
    letter-spacing: -.01em;
    font-weight: 650;
}

.lead {
    margin: 0 0 1.25rem;
    color: var(--muted);
    font-size: .93rem;
}

.lead code,
.opts code {
    font-family: var(--mono);
    font-size: .88em;
    color: var(--accent);
    background: var(--accent-soft);
    border-radius: 4px;
    padding: .1em .35em;
}

/* ---------------------------------------------------------------
   Map containers
   --------------------------------------------------------------- */
.geomap {
    width: 100%;
    /* 12 / 6.1, the board these examples actually declare — not 2/1, which
       was 1.7 % off and letterboxed every one of them by a hair. */
    aspect-ratio: 12 / 6.1;
    border-radius: var(--radius-s);
    overflow: hidden;
    border: 1px solid var(--border);
    background: var(--surface-2);
}

/* On phones the 2:1 sheet gets too flat to read, so a plain map is given more
   height. Only a plain map: every modifier carries a ratio chosen for what it
   holds, and forcing 3/2 on those letterboxes them. --half is a globe in a
   wide board at 2.07 and would have gained empty strips above and below. */
@media (max-width: 34rem) {
    .geomap:not(.geomap--tall):not(.geomap--disc):not(.geomap--half):not(.geomap--globe) {
        aspect-ratio: 3 / 2;
    }
}

/* Boards whose bounding box is not 2:1 — the container has to match,
   otherwise keepaspectratio letterboxes or crops the map. */
.geomap--tall { aspect-ratio: 12 / 11.3; }   /* Mercator, cut at 84°   */
.geomap--disc { aspect-ratio: 12 / 11.6; }   /* azimuthal projections  */

/* A globe at half height: the sphere keeps its own square rectangle inside a
   wide board, so the page stays readable without a column of tall cards. */
.geomap--half { aspect-ratio: 12 / 5.8; }

/* Three by two, for a globe that is the point of the example rather than one
   half of a pair. At 2:1 the sphere filled 38 % of the width; here it fills
   57 %, which is 48 % larger across. */
.geomap--globe { aspect-ratio: 3 / 2; }

/* appBox: outer box 12 x 8 — three button rows above the map area.
   The container carries the ratio itself, and everything the appBox
   builds inside it is stretched to fill; relying on the inline
   aspect-ratio of the inner jxgbox alone collapses the height. */
.geoapp {
    width: 100%;
    aspect-ratio: 12 / 8;
    border-radius: var(--radius-s);
    border: 1px solid var(--border);
    background: var(--surface-2);
    padding: .25rem;
}

/* The strip above the drawing area holds as many rows of controls as the
   example needs, and the board is sized to that: with the fixed 12x8 an
   example with one row left 1.1 units empty above it, and the map filled
   65 % of the height instead of 80. */
.geoapp--1row  { aspect-ratio: 12 / 6.5; }
.geoapp--2rows { aspect-ratio: 12 / 7.1; }

/* Three rows above a map that is drawn full width — the projection switcher,
   whose twelve buttons need four to a row to clear each other. */
.geoapp--3rows-wide { aspect-ratio: 12 / 8.3; }
.geoapp--4rows-wide { aspect-ratio: 12 / 10; }

/* One row above a pair of drawings that are only 4.3 units tall themselves. */
.geoapp--flat { aspect-ratio: 12 / 5.5; }

/* A globe of 6.8 units with one or two rows of buttons above it. Five
   buttons need two rows: one runs to 8.6rem, so they are spaced 2.6 units
   apart, and four is what fits across the twelve. */
.geoapp--globe1 { aspect-ratio: 12 / 8.3; }
.geoapp--globe2 { aspect-ratio: 12 / 8.9; }

/* A map beside a globe with one row above them. */
.geoapp--pair1 { aspect-ratio: 12 / 5.9; }

/* A globe of 6.8 units with one or two rows of buttons above it. A button
   runs to 8.6rem and needs 2.6 units of spacing to clear its neighbour on a
   board rendered at 700 px, so four fit across the twelve and five views take
   two rows. */
.geoapp--globe1 { aspect-ratio: 12 / 8.3; }
.geoapp--globe2 { aspect-ratio: 12 / 8.9; }

/* A map beside a globe, with one row above them. */
.geoapp--pair1 { aspect-ratio: 12 / 5.9; }
.geoapp--pair2 { aspect-ratio: 12 / 7; }

/* A map beside a globe and no controls at all: with the 12x8 strip they sat
   in the lower half with 3.5 units empty above, and the globe filled 54 % of
   the height instead of 92. */
.geoapp--pair { aspect-ratio: 12 / 4.9; }

.geoapp > div,
.geoapp .jxgbox {
    width: 100% !important;
    height: 100% !important;
    aspect-ratio: auto !important;
    background: transparent;
    border: 0;
}

/* The focus ring the browser draws on a clicked path. `tabindex`
   defaults to -1, which leaves an element focusable by mouse, and the
   ocean is one path spanning the whole map — so a click anywhere put a
   ring around the picture. The maps set `tabindex: null`, which is the
   proper fix; this is the backstop for anything that slips through.

   `:focus-visible` rather than `:focus`, so the ring survives for
   keyboard users, where it is the only sign of where they are. */
/* No ring on the drawing itself, keyboard or not: a curve is not a control,
   and `tabindex: null` on every layer is what actually keeps it out of the
   tab order. The buttons and links around it keep their ring. */
.jxgbox :focus,
.jxgbox :focus-visible {
    outline: none;
}

/* ---------------------------------------------------------------
   Buttons drawn inside a board (JSXGraph cssClass)
   --------------------------------------------------------------- */
.ui-btn button,
.ui-on button {
    width: clamp(4.2rem, 20vw, 8.6rem) !important;
    max-width: 100%;
    padding: .32rem .5rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--accent);
    font-family: var(--font);
    font-size: clamp(.6rem, 1.9vw, .78rem);
    font-weight: 550;
    line-height: 1.25;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: background .15s, color .15s, border-color .15s;
}

.ui-btn button:hover {
    background: var(--accent-soft);
    border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}

.ui-on button {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--surface);
    font-weight: 650;
}

/* ---------------------------------------------------------------
   Checkboxes drawn inside a board (JSXGraph cssClass)
   --------------------------------------------------------------- */
/* The label is a <label> beside the input, not the node JSXGraph
   colours through `strokeColor`. A class rule on the label beats that
   attribute, so the colour has to be named here — without it the
   labels are not there at all. */
.ui-chk,
.ui-chk label {
    font-family: var(--font);
    font-size: clamp(.62rem, 1.9vw, .8rem);
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
    white-space: nowrap;
}

.ui-chk input {
    accent-color: var(--accent);
    margin-right: .4rem;
    vertical-align: -1px;
    cursor: pointer;
}

/* ---------------------------------------------------------------
   Read-out under a map
   --------------------------------------------------------------- */
/* The line between an example's two drawing areas: it names what the second
   one is for without taking a heading, which would make one example look like
   two. */
.boxnote {
    margin: 1.1rem 0 .5rem;
    font-size: .82rem;
    color: var(--muted);
    font-style: italic;
}

.readout {
    margin: .9rem 0 0;
    font-family: var(--mono);
    font-size: .8rem;
    color: var(--muted);
}

.readout:empty { display: none; }

/* ---------------------------------------------------------------
   Property list
   --------------------------------------------------------------- */
/* Links in the body of the page. Without this they fall back to the browser's
   own purple and its red while the pointer is down, neither of which belongs
   here. --accent is defined once per colour scheme and measures 8.5 against
   the dark surface and 7.2 against the light one; :visited is given the same
   colour on purpose, since which pages have been read is nobody's business
   and the violet was the complaint. */
main a,
.footer a {
    color: var(--accent);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: .15em;
}

main a:visited,
.footer a:visited { color: var(--accent); }

main a:hover,
.footer a:hover { text-decoration-thickness: 2px; }

main a:active,
.footer a:active { color: var(--accent); opacity: .75; }

dl.opts {
    margin: 1.25rem 0 0;
    display: grid;
    grid-template-columns: 10rem 1fr;
    gap: .1rem .9rem;
    font-size: .88rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-s);
    padding: 1rem 1.1rem;
}

dl.opts:empty { display: none; }

dl.opts dt {
    color: var(--muted);
    text-transform: uppercase;
    font-size: .7rem;
    font-weight: 650;
    letter-spacing: .07em;
    padding-top: .32rem;
}

dl.opts dd {
    margin: 0 0 .55rem;
    max-widthh: 62ch;
}

dl.opts dd:last-of-type { margin-bottom: 0; }

@media (max-width: 40rem) {
    dl.opts { grid-template-columns: 1fr; }

    dl.opts dt { padding-top: .5rem; }

    dl.opts dd { margin-bottom: .35rem; }
}

/* ---------------------------------------------------------------
   Site menu — switches between the three pages
   --------------------------------------------------------------- */
/* Both bars in one sticky element. The second needs no offset for the first
   that way, which matters because the first is not one height: one row of
   links at 1280 px, three at 1024, four at 390. A fixed `top` on the jump
   list would have it overlapping or floating at every width but one.

   Below 46rem the two come to about 292 px together — more than half a phone
   screen before a word is read — so there they scroll away with the page. */
.stickybar {
    position: sticky;
    top: 0;
    z-index: 50;
}

@media (max-width: 46rem) {
    .stickybar { position: static; }
}

/* Lime, with the logo's own blue on top of it.
   Contrast against #12437c, the one colour the logo is drawn in: 6.55. WCAG
   wants 4.5 for text and 3 for graphics, so the mark and the links both clear
   it comfortably. White would have been 1.51 and unreadable — which is why
   nothing on this bar is white. */
.topbar {
    background: var(--lime);
    color: var(--lime-ink);
    border-bottom: 1px solid rgba(18, 67, 124, .18);
}

.topbar__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem 1.25rem;
    min-height: 3rem;
    padding: .4rem 0;
}

.topbar__brand {
    display: flex;
    align-items: center;
    margin-right: auto;
    text-decoration: none;
    padding: .1rem 0;
}

/* The logo is 963.78 by 192.76, so exactly 5:1; the height is what is set and
   the width follows. It carries its own colour and needs no filter on lime. */
.topbar__brand img {
    height: 2rem;
    width: auto;
    display: block;
}

/* Where the links stack into three rows the bar is about 100 px tall and the
   mark beside it may as well use the room; at one row it would tower over
   them. */
@media (max-width: 70rem) {
    .topbar__brand img { height: 2.6rem; }
}

@media (max-width: 40rem) {
    .topbar__brand img { height: 2.1rem; }
}

/* The bar wraps rather than scrolls. Measured at the sizes in geo.css: the
   brand and the three groups need about 994 px in one row, so anything under
   1024 has to give somewhere. `overflow-x: auto` with the scrollbar hidden —
   what stood here — gave nothing: the row was cut off with no sign that there
   was more, which is what it was taken for.

   A group wraps as a unit, because .navgroup is a flex item of its own; a
   label never ends up on a different line from its links. */
.topbar__links {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem .3rem;
    max-width: 100%;
}

.topbar__links a {
    flex: 0 0 auto;
    color: var(--lime-ink);
    text-decoration: none;
    font-size: .85rem;
    font-weight: 500;
    padding: .35rem .8rem;
    border-radius: 999px;
    white-space: nowrap;
    transition: background .15s, color .15s;
}

/* Darker lime rather than a white veil: white on lime is a contrast of 1.51,
   so anything tinted towards it takes the text with it. */
.topbar__links a:hover,
.topbar__links a:focus-visible {
    background: rgba(18, 67, 124, .12);
}

.topbar__links a[aria-current="page"] {
    color: var(--lime);
    background: var(--lime-ink);
    font-weight: 650;
}

/* A group of pages that belong to one element: "Map: Properties Projections
   Interactions". Without the label both elements would need the word
   Properties spelled out, and the bar reads worse for it.

   The gap between groups is wider than the gap inside one, which is what
   makes the grouping visible at all; the rule on .topbar__links sets the
   narrow one. */
.navgroup {
    display: flex;
    align-items: center;
    gap: .3rem;
    flex: 0 0 auto;
}

.navgroup + .navgroup { margin-left: 1.1rem; }

/* The label has to stay quieter than the links without falling below
   readable: 3.23 against the lime — under the 4.5 WCAG asks of body text,
   over the 3 it asks of the large, spaced, bold type this is set in. */
.navgroup__label {
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--lime-dim);
    white-space: nowrap;
    padding-right: .1rem;
}

/* A group may be written without a title, and then it is drawn as loose
   entries that still need to stand apart from the group before them. All
   three groups carry a title today, so this matches nothing — it is here for
   the case, not for the current menu. */
.navgroup:not([aria-label]) {
    border-left: 1px solid rgba(18, 67, 124, .22);
    padding-left: 1.1rem;
}

/* Below the width where all three fit beside the brand, each group takes a
   line of its own: three short rows read better than two ragged ones, and the
   labels line up down the left.

   1058 px for the brand and the three groups, plus the 32 px the wrap keeps
   at the sides, so they stop fitting at about 1090. The breakpoint stood at
   62rem — 992 px — while the third group was still unlabelled and the bar was
   64 px narrower; naming it Shared pushed it past. */
@media (max-width: 70rem) {
    .topbar__links { flex-direction: column; align-items: flex-start; }

    .navgroup { width: 100%; }

    .navgroup + .navgroup { margin-left: 0; }

    /* The same case, stacked: the rule separates rows, not columns. */
    .navgroup:not([aria-label]) {
        border-left: 0;
        padding-left: 0;
        border-top: 1px solid rgba(18, 67, 124, .22);
        padding-top: .35rem;
    }

    .navgroup__label {
        min-width: 3.4rem;      /* the links start at one place, not three */
    }
}

/* The widest group, Map, needs about 384 px for its label and three links.
   Below that it wraps inside itself, and a label left hanging beside half its
   links reads worse than one on a line of its own. */
@media (max-width: 27rem) {
    .navgroup { flex-wrap: wrap; }

    .navgroup__label {
        width: 100%;
        min-width: 0;
        padding-bottom: .1rem;
    }
}

/* On a phone the bar comes to four rows and about 126 px counting the brand.
   That is a third of the screen, but it scrolls away with the page — .topbar
   is not sticky, only the section nav below it is — so it costs that height
   once rather than all the time. Tighter gaps make it a little less. */
@media (max-width: 40rem) {
    .topbar__inner { gap: .25rem .8rem; padding: .3rem 0; }

    .topbar__links { gap: .25rem; }

    .topbar__links a { padding: .3rem .6rem; }
}

/* ---------------------------------------------------------------
   Code panels
   --------------------------------------------------------------- */
.panels {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-top: 1.25rem;
}

.panel {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-s);
    overflow: hidden;
}

.panel__title {
    margin: 0;
    padding: .7rem .95rem;
    font-size: .76rem;
    font-weight: 650;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
    border-bottom: 1px solid var(--border);
}

pre {
    margin: 0;
    padding: .9rem 1rem 1.1rem;
    background: var(--code-bg);
    color: var(--code-fg);
    font-family: var(--mono);
    font-size: .8rem;
    line-height: 1.55;
    overflow-x: auto;
    tab-size: 4;
}

/* ---------------------------------------------------------------
   Footer
   --------------------------------------------------------------- */
.footer {
    border-top: 1px solid var(--border);
    padding: 1.75rem 0 3rem;
    color: var(--muted);
    font-size: .82rem;
    display: flex;
    flex-wrap: wrap;
    gap: .75rem 1.5rem;
    justify-content: space-between;
}

/* The three footer links sit together and wrap as a group on a narrow
   screen rather than one falling to a line of its own. */
.footer__links {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.1rem;
}

.footer a { color: var(--accent); }