/*==========================================================================
   DESIGN BY RACHEL WONG — global stylesheet
   Built mobile-first. Navbar measurements taken from the Illustrator
   blueprints (8001px export = 1920px design, scale factor 4.167).
==========================================================================*/

/*--------------------------------------------------------------------------
   Tokens — colours from WebsiteDesignAssetsSwatch.pdf / Swatch.svg
--------------------------------------------------------------------------*/
:root {
    --red:    #9c4545;
    --yellow: #b5802b;
    --teal:   #287492;
    --grey:   #a6b8c7;
    --navy:   #092d59;
    --blue:   #153a70;
    --purple: #8047b0;
    --white:  #ffffff;

    /* One percent of the mobile design's width. The designer's mobile
       reference gives every measurement as a share of the page, so the
       phone-sized furniture is written in this unit. It stops growing at a
       640px design width, which keeps a tablet from rendering the page as a
       very large phone. */
    --u: min(1vw, 6.4px);

    /* Navbar — mobile, at the reference's proportions: a bar 6.66% of the
       page tall, logo 7.79% wide, both inset 4.46% from the edge. */
    --nav-height:    calc(var(--u) * 6.66);
    --nav-pad-x:     calc(var(--u) * 4.46);
    --nav-logo-w:    calc(var(--u) * 7.79);
    --nav-font-size: 1.0625rem;   /* the drop-down panel, not the bar */
    --nav-gap:       1.5rem;

    /* Hamburger, same source: 3.00% wide with its three bars 1.09% apart. */
    --nav-burger-w:   calc(var(--u) * 3.0);
    --nav-burger-bar: max(1.5px, calc(var(--u) * 0.29));
    --nav-burger-gap: calc(var(--u) * 1.09);

    --squiggle-height: 0.21em;  /* blueprint: constant ~5px at 24px type */
    --squiggle-offset: 0.30em;  /* blueprint: sits ~6px under the baseline */

    --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

/* Desktop — values below resolve to the blueprint's exact pixels at 1920px:
   height 86px · padding 55px · logo 90.9px · type 24px · gap 24px          */
@media (min-width: 48em) {
    :root {
        --nav-height:    clamp(4rem,     4.50vw, 5.375rem);
        --nav-pad-x:     clamp(1.5rem,   2.90vw, 3.4375rem);
        --nav-logo-w:    clamp(3.75rem,  4.73vw, 5.68rem);
        --nav-font-size: clamp(0.9375rem, 1.25vw, 1.5rem);
        --nav-gap:       clamp(1rem,     1.25vw, 1.5rem);
    }
}

/*--------------------------------------------------------------------------
   Reset / base
--------------------------------------------------------------------------*/
*,
*::before,
*::after { box-sizing: border-box; }

/* A column so the footer is pushed to the bottom on a page shorter than the
   window — Contact is 1019px tall, which would otherwise leave a band of
   body showing under the footer on a 1080p screen. Each page sets `body`'s
   background to whatever its last section uses, so the strip main grows into
   matches the section above it. */
body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    margin: 0;
    font-family: "Raleway", system-ui, -apple-system, "Segoe UI", sans-serif;
    font-weight: 400;
    color: var(--navy);
    background: var(--white);
    -webkit-font-smoothing: antialiased;
}

main {
    flex: 1 0 auto;
    /* The watermark on a capped section runs out past that section to the
       window's edges, and 100vw counts a classic scrollbar. Clipping the one
       axis keeps that from adding a sliver of horizontal scroll; clip rather
       than hidden, so it stays visible vertically — the intro's waterfall
       deliberately hangs below its section. */
    overflow-x: clip;
}

.site-footer {
    flex: none;
}

img { display: block; max-width: 100%; }
ul  { margin: 0; padding: 0; list-style: none; }
a   { color: inherit; text-decoration: none; }

button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.skip-link {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 200;
    padding: 0.5rem 0.875rem;
    background: var(--white);
    color: var(--blue);
    border-radius: 0.25rem;
    transform: translateY(-200%);
    transition: transform 0.2s var(--ease);
}

.skip-link:focus-visible { transform: none; }

/*==========================================================================
   NAVBAR
==========================================================================*/
.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--blue);
    color: var(--white);
}

.nav {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--nav-gap);
    height: var(--nav-height);
    padding-inline: var(--nav-pad-x);
}

.nav__logo {
    position: relative;
    display: block;
    flex: none;
    margin-right: auto;
}

/* Same invisible pad as the footer icons: the mobile bar is small. */
.nav__logo::after {
    content: "";
    position: absolute;
    inset: -0.5rem;
}

.nav__logo img {
    width: var(--nav-logo-w);
    height: auto;
}

/*--------------------------------------------------------------------------
   Links + NavSquiggle underline
--------------------------------------------------------------------------*/
/* Padding is symmetrical on purpose: it centres the *text* in the bar and
   lets the squiggle hang into the space below it, which is how the blueprint
   sits (the type there is ~4px lower than a naive centring would put it).
   It also gives the links a comfortable tap target on mobile. */
.nav__link {
    position: relative;
    display: inline-block;
    line-height: 1;
    padding-block: var(--squiggle-offset);
    font-size: var(--nav-font-size);
    font-weight: 400;
}

/* The squiggle is drawn as a mask filled with the link's own colour, so it
   stretches to the full width of each word at a constant thickness — exactly
   how the designer set it in the blueprints.
   The squiggle comes from css/svg-inline.css as a data URI rather than a
   link: Chromium will not load an external SVG as a mask over file://, and
   fails silently when it can't. Source: assets/SVG/NavSquiggle.svg */
.nav__link::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: var(--squiggle-height);
    background-color: currentColor;
    -webkit-mask: var(--mask-squiggle-nav) no-repeat center / 100% 100%;
            mask: var(--mask-squiggle-nav) no-repeat center / 100% 100%;
    clip-path: inset(0 50% 0 50%);            /* hidden: closed from the centre */
    transition: clip-path 0.3s var(--ease);
}

/* The page you are on is underlined the whole time. */
.nav__link[aria-current="page"]::after {
    clip-path: inset(0 0 0 0);
}

/* Hover is gated behind a real pointer so a tap on a phone can't leave a
   second underline stuck on. */
@media (hover: hover) {
    .nav__link:hover::after {
        clip-path: inset(0 0 0 0);
    }

    /* ...and the moment another link is hovered, the current page's squiggle
       retracts, so only one underline is ever showing. */
    .nav__list:has(.nav__link:hover) .nav__link[aria-current="page"]:not(:hover)::after {
        clip-path: inset(0 50% 0 50%);
    }
}

/* Same trade for keyboard users. */
.nav__link:focus-visible::after {
    clip-path: inset(0 0 0 0);
}

.nav__list:has(.nav__link:focus-visible) .nav__link[aria-current="page"]:not(:focus-visible)::after {
    clip-path: inset(0 50% 0 50%);
}

/* The squiggle alone can't signal focus on the link that is already
   underlined, so keyboard focus also gets a ring. */
.nav__link:focus-visible,
.nav__logo:focus-visible,
.nav__toggle:focus-visible {
    outline: 2px solid var(--white);
    outline-offset: 4px;
    border-radius: 2px;
}

/*--------------------------------------------------------------------------
   Mobile: hamburger + drop-down panel
--------------------------------------------------------------------------*/
/* The button is wider and taller than the bars it draws, so the tap target
   stays comfortable at the size the reference sets them. It runs out to the
   page edge and holds the bars against its own right padding, which puts
   them 2% in from the edge as the reference has them without the button
   itself sticking out past the viewport. */
.nav__toggle {
    flex: none;
    display: grid;
    place-items: center end;
    width: calc(var(--nav-burger-w) + var(--u) * 2 + 1.25rem);
    height: max(100%, 2.25rem);
    padding-right: calc(var(--u) * 2);
    margin-right: calc(var(--nav-pad-x) * -1);
}

.nav__toggle-bars {
    position: relative;
    display: block;
    width: var(--nav-burger-w);
    height: var(--nav-burger-bar);
    background: currentColor;
    border-radius: 2px;
    transition: background-color 0.2s var(--ease);
}

.nav__toggle-bars::before,
.nav__toggle-bars::after {
    content: "";
    position: absolute;
    left: 0;
    width: 100%;
    height: 100%;
    background: currentColor;
    border-radius: inherit;
    transition: transform 0.25s var(--ease);
}

.nav__toggle-bars::before { top: calc(var(--nav-burger-gap) * -1); }
.nav__toggle-bars::after  { top: var(--nav-burger-gap); }

.nav[data-open="true"] .nav__toggle-bars { background-color: transparent; }
.nav[data-open="true"] .nav__toggle-bars::before { transform: translateY(var(--nav-burger-gap)) rotate(45deg); }
.nav[data-open="true"] .nav__toggle-bars::after  { transform: translateY(calc(var(--nav-burger-gap) * -1)) rotate(-45deg); }

.nav__list {
    position: absolute;
    inset: 100% 0 auto 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.5rem;
    padding: 1.75rem var(--nav-pad-x) 2.25rem;
    background: var(--blue);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-0.625rem);
    transition: opacity 0.25s var(--ease),
                transform 0.25s var(--ease),
                visibility 0s linear 0.25s;
}

.nav[data-open="true"] .nav__list {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
}

/*--------------------------------------------------------------------------
   Desktop: single horizontal row, no hamburger
--------------------------------------------------------------------------*/
@media (min-width: 48em) {
    .nav__toggle { display: none; }


    .nav__list {
        position: static;
        flex-direction: row;
        align-items: baseline;
        gap: var(--nav-gap);
        padding: 0;
        background: none;
        opacity: 1;
        visibility: visible;
        transform: none;
        transition: none;
    }
}

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

/*==========================================================================
   TEMPORARY — placeholder body copy so the sticky navbar can be reviewed.
   Delete as each page gets built.
==========================================================================*/
.placeholder {
    min-height: 160vh;
    display: grid;
    place-content: center;
    gap: 0.5rem;
    padding: 4rem 1.5rem;
    text-align: center;
    color: var(--grey);
}

.placeholder h1 {
    margin: 0;
    font-size: clamp(1.5rem, 4vw, 2.5rem);
    font-weight: 600;
    color: var(--blue);
}

/*==========================================================================
   FOOTER
   Measured off the blueprint the same way as everything else (8001px export
   = a 1920px design, divide by 4.167): an 81.1px bar in #153A70, the
   wordmark and the icons both at their native size, 63.6px in from each
   edge, and the badge centred and overlapping the bar's top edge.
   FooterBar.svg is not needed — the bar is a plain rectangle, and building
   it in markup keeps the three social links separately clickable.
==========================================================================*/
:root {
    /* Mobile, at the reference's proportions. */
    --footer-h:        calc(var(--u) * 7.06);
    --footer-pad-x:    calc(var(--u) * 2.0);
    /* The reference insets the wordmark further than the icons. */
    --footer-pad-right: calc(var(--u) * 4.0);
    --footer-wordmark: calc(var(--u) * 24.12);
    --footer-icon:     calc(var(--u) * 4.20);
    --footer-icon-gap: calc(var(--u) * 2.33);
    --footer-badge:    calc(var(--u) * 8.13);

    /* The badge hangs 37% of its height above the bar, into whatever section
       sits above it. A last section has to reserve this much plus a gap, or
       its final lines run into the badge. */
    --footer-badge-clear: calc(var(--footer-badge) * 0.374 + 1.5rem);
}

/* Desktop — the values the 1920 blueprint sets. */
@media (min-width: 48em) {
    :root {
        --footer-h:        max(3.25rem, 4.22vw);   /* 81.1px at 1920 */
        --footer-pad-x:    max(1rem, 3.31%);       /* 63.6px at 1920 */
        --footer-pad-right: max(1rem, 3.31%);
        --footer-wordmark: max(8rem, 12.44vw);     /* 238.8px at 1920 */
        --footer-icon:     max(1.15rem, 1.09vw);   /* 20.9px at 1920 */
        --footer-icon-gap: max(0.4rem, 0.61vw);    /* 11.8px at 1920 */
        --footer-badge:    max(3.25rem, 5.29vw);   /* 101.6px at 1920 */
    }
}

.site-footer {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: var(--footer-h);
    padding-left: var(--footer-pad-x);
    padding-right: var(--footer-pad-right);
    background: var(--blue);
    color: var(--white);
}

/* The badge is centred on the bar, so the wordmark's room is half of what
   is left once the badge is taken out. Capping it there means it can never
   run into the badge, at any width, without needing a breakpoint. */
.site-footer__wordmark {
    width: var(--footer-wordmark);
    max-width: calc((100% - var(--footer-badge)) / 2 - 0.75rem);
    height: auto;
}

/* The badge sits over the bar's top edge, 37% of it above the line. Above
   the bar it is white on white, so only its ring text and the mountain
   read — which is how the blueprint has it. */
.site-footer__badge {
    position: absolute;
    left: 50%;
    top: calc(var(--footer-badge) * -0.374);
    width: var(--footer-badge);
    transform: translateX(-50%);
}

.site-footer__badge img {
    width: 100%;
    height: auto;
}

.site-footer__social {
    display: flex;
    align-items: center;
    gap: var(--footer-icon-gap);
}

/* The icons are small at the size the reference sets them, so each link
   carries an invisible pad that widens the tap target. A pseudo-element
   rather than padding, so the spacing between the icons is untouched. */
.site-footer__social a {
    position: relative;
    display: block;
    border-radius: 0.25rem;
}

.site-footer__social a::after {
    content: "";
    position: absolute;
    inset: -0.3rem;
}

.site-footer__social img {
    width: var(--footer-icon);
    height: auto;
}

.site-footer__badge:focus-visible,
.site-footer__social a:focus-visible {
    outline: 2px solid var(--white);
    outline-offset: 4px;
}

@media (hover: hover) {
    .site-footer__social a {
        transition: transform 0.2s var(--ease);
    }

    .site-footer__social a:hover {
        transform: translateY(-2px);
    }
}


/*==========================================================================
   PAGE FURNITURE — the watermark ground and the wave that divides sections.
   Shared by every page, so it lives here rather than in a page stylesheet.
==========================================================================*/
:root {
    --divider-h: max(1.1rem, 3.14vw);   /* PageDivider: 60.2px at 1920 */
    --divider-half: calc(var(--divider-h) / 2);
    /* The artwork carries its own opacity now (5% in the file), so this
       stays at 1 unless someone wants to tune it without a new export. */
    --watermark-opacity: 1;
}

.watermarked {
    position: relative;
    isolation: isolate;
    background: #fdfdfd;
}

.watermarked::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: url("../assets/SVG/WatermarkBackground-TILE.svg") repeat;
    background-size: max(9rem, 15.1vw) auto;   /* the tile at its native 290px at 1920 */
    opacity: var(--watermark-opacity);
    pointer-events: none;
}

/* The two sections meet at a straight seam and the wave is laid over it,
   rather than the wave occupying a gap between them. PageDivider.svg is 62
   units tall with its top edge inside y 0-20 and its bottom edge inside
   y 40-60, so a band centred on the seam always covers it: above the wave
   only the upper section shows, below it only the lower one, at any width.
   The band takes no room in the flow — each section pays for its own half
   through padding, so the sections' own backgrounds (and the waterfalls
   pinned to their edges) run right into it and are tucked underneath. */
.divider {
    position: relative;
    z-index: 5;
    height: 0;
}

.divider::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: calc(var(--divider-half) * -1);
    height: var(--divider-h);
    background: var(--svg-page-divider) no-repeat center / 100% 100%;
}



/*==========================================================================
   FLIP — a badge that turns over on hover or focus. Used by the homepage
   hero icons and CTAs, and by the Projects category badges.
==========================================================================*/
.flip {
    display: block;
    perspective: 900px;
}

.flip__inner {
    position: relative;
    display: block;
    transform-style: preserve-3d;
    transition: transform 0.55s var(--ease);
}

.flip__face {
    display: block;
    width: 100%;
    height: auto;
    backface-visibility: hidden;
}

.flip__face--back {
    position: absolute;
    inset: 0;
    transform: rotateY(180deg);
}

@media (hover: hover) {
    .flip:hover .flip__inner { transform: rotateY(180deg); }
}

.flip:focus-visible {
    outline: none;
}

.flip:focus-visible .flip__inner {
    transform: rotateY(180deg);
}

.flip:focus-visible .flip__face {
    outline: 2px solid var(--blue);
    outline-offset: 6px;
    border-radius: 50%;
}

/* The "featured work" fan is centred on the wave and hangs below it —
   256x143 at 1920, sitting 5px lower than the wave's own centre. */
.divider__badge {
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(5.5rem, 13.33vw);
    height: auto;
    transform: translate(-50%, -50%) translateY(0.26vw);
}

