@font-face {
    font-family: 'Archivo';
    font-style: normal;
    font-weight: 100 900;
    font-stretch: 62% 125%;
    font-display: swap;
    src: url('/assets/fonts/archivo-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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Archivo';
    font-style: normal;
    font-weight: 100 900;
    font-stretch: 62% 125%;
    font-display: swap;
    src: url('/assets/fonts/archivo-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;
}

@font-face {
    font-family: 'Spline Sans Mono';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('/assets/fonts/splinemono-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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Spline Sans Mono';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('/assets/fonts/splinemono-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;
}
/* ─────────────────────────────────────────────────────────────
   rasmuskruse.dk
   Palet: natten i en sal. Varm næsten-sort som væg, knoglehvid
   som papir, og natrium-ravgul — farven på arbejdslyset i et
   tomt lokale. Én kold tone som modspil til kode-halvdelen.
   ───────────────────────────────────────────────────────────── */

:root {
    --ink: #0B0A09;
    --ink-raised: #16130F;
    --bone: #EDE7DD;
    --dim: #7C736A;
    --line: #2A2521;
    --amber: #F5A03C;

    --gutter: clamp(1.25rem, 5vw, 5rem);
}

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

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

body {
    margin: 0;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    background: var(--ink);
    color: var(--bone);
    font-family: 'Archivo', system-ui, sans-serif;
    font-variation-settings: 'wdth' 100;
    font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

/* Signaturen: et wash-lys der langsomt trækker hen over væggen
   bag navnet, som en lampe der scanner et tomt lokale. */
.wash {
    position: fixed;
    top: -45vh;
    left: -70vw;
    width: 110vw;
    height: 150vh;
    rotate: -14deg;
    z-index: 0;
    pointer-events: none;
    background: radial-gradient(
        ellipse 34% 50% at 50% 50%,
        rgba(245, 160, 60, 0.26),
        rgba(245, 160, 60, 0.09) 46%,
        transparent 74%
    );
    filter: blur(30px);
    animation: sweep 26s ease-in-out infinite alternate;
}

@keyframes sweep {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(125vw, 10vh, 0) scale(1.15); }
}

/* Film-korn over hele fladen, portrættet inklusive. Store flader varm
   næsten-sort bånder på billige paneler; kornet bryder gradienten og
   binder foto og baggrund sammen. Ét inline-SVG, intet request. */
.grain {
    position: fixed;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    opacity: 0.045;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Indgang: teksten sætter sig linje for linje. Forsinkelserne holdes under
   200 ms — Chrome registrerer først LCP når elementet har opacity over 0, så
   længere stagger ville flytte målingen. */
@keyframes rise {
    from { opacity: 0; transform: translate3d(0, 14px, 0); }
    to   { opacity: 1; transform: none; }
}

@keyframes emerge {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.topline { animation: rise 620ms cubic-bezier(0.2, 0.7, 0.3, 1) 40ms both; }
.name   { animation: rise 700ms cubic-bezier(0.2, 0.7, 0.3, 1) 90ms both; }
.lead   { animation: rise 640ms cubic-bezier(0.2, 0.7, 0.3, 1) 150ms both; }
.linkedin { animation: rise 620ms cubic-bezier(0.2, 0.7, 0.3, 1) 200ms both; }
.refs   { animation: rise 620ms cubic-bezier(0.2, 0.7, 0.3, 1) 260ms both; }
.systems { animation: rise 620ms cubic-bezier(0.2, 0.7, 0.3, 1) 310ms both; }
.portrait { animation: emerge 900ms ease-out both; }

/* ── Scenen: tekst til venstre, portræt til højre ── */

.stage {
    position: relative;
    z-index: 1;
    flex: 1 1 auto;
    display: grid;
    /* Lige spalter. Portrættet ligger i sit fulde, liggende format og har
       brug for bredden — beskåret til 4:5 klarede det sig med mindre. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: clamp(2rem, 5vw, 4.5rem);
    padding: clamp(1.75rem, 4.5vh, 3.5rem) var(--gutter);
    max-width: 82rem;
    width: 100%;
    margin: 0 auto;
}

.intro {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: clamp(0.9rem, 2vh, 1.5rem);
    min-width: 0;
}

/* Rolle og sprogskifte på samme mono-linje. Sprogskiftet stod først
   højrestillet i spalten, men landede så midt i det tomme felt mellem tekst
   og portræt uden at høre til noget. Tættere på rollen læser det som den
   lille hjælpefunktion det er. */
.topline {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.9rem;
}

.role {
    margin: 0;
    font-family: 'Spline Sans Mono', ui-monospace, monospace;
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--amber);
}

.lang {
    flex: 0 0 auto;
    font-family: 'Spline Sans Mono', ui-monospace, monospace;
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--dim);
    text-decoration: none;
    transition: color 140ms ease;
}

.lang::before {
    content: "·";
    margin-right: 0.9rem;
    opacity: 0.5;
}

.lang:hover,
.lang:focus-visible { color: var(--bone); }

/* Navnet er heroen: bredt, tungt, tæt sat. Bredden er det
   uventede valg — kondenseret ville have været det nemme. */
.name {
    margin: 0;
    font-size: clamp(2.5rem, min(8.5vw, 10.5vh), 6.5rem);
    font-weight: 800;
    font-variation-settings: 'wdth' 118;
    line-height: 0.84;
    letter-spacing: -0.035em;
    text-transform: uppercase;
}

.name-line { display: block; }

/* 404-siden bruger samme navnebehandling, men må ikke skrige lige så højt */
.name-sm { font-size: clamp(2.25rem, min(7vw, 10vh), 5rem); }

.lead {
    margin: 0;
    max-width: 40ch;
    font-size: clamp(1rem, 0.94rem + 0.5vw, 1.25rem);
    font-weight: 400;
    line-height: 1.45;
    /* Et hak under knoglehvid: navnet skal blive det tungeste på siden */
    color: rgba(237, 231, 221, 0.82);
    text-wrap: pretty;
}

.linkedin {
    margin-top: 0.35rem;
    display: inline-flex;
    align-items: center;
    gap: 0.6em;
    padding: 0.7rem 1.15rem;
    color: var(--ink);
    background: var(--bone);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9375rem;
    transition: background 140ms ease, color 140ms ease;
}

.linkedin-glyph { flex: 0 0 auto; }
.linkedin-arrow { transition: transform 180ms cubic-bezier(0.2, 0.7, 0.3, 1); }

.linkedin:hover,
.linkedin:focus-visible { background: var(--amber); color: var(--ink); }
.linkedin:hover .linkedin-arrow,
.linkedin:focus-visible .linkedin-arrow { transform: translate(2px, -2px); }

/* ── Referencer og systemer ──
   Diskret med vilje: navnet skal stadig være det første man ser. Derfor
   mono-mærkater i dæmpet grå, lille tekst og ingen kort eller rammer. */

.micro {
    margin: 0 0 0.7rem;
    font-family: 'Spline Sans Mono', ui-monospace, monospace;
    font-size: 0.625rem;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--dim);
}

.refs,
.systems { width: 100%; }

.refs { margin-top: 0.4rem; }

.ref-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.ref-list li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.2rem 0.75rem;
    font-size: 0.9375rem;
}

.ref-list a {
    color: var(--bone);
    text-decoration: none;
    /* Hårfin understregning frem for underline: linjen skal kunne skifte
       farve på hover uden at teksten hopper */
    border-bottom: 1px solid var(--line);
    transition: color 140ms ease, border-color 140ms ease;
}

.ref-list a:hover,
.ref-list a:focus-visible {
    color: var(--amber);
    border-color: var(--amber);
}

.ref-note {
    font-family: 'Spline Sans Mono', ui-monospace, monospace;
    font-size: 0.6875rem;
    letter-spacing: 0.04em;
    color: var(--dim);
}

.system-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.75rem;
}

/* Logoerne er gengivet monokromt i sidens palet og holdes nede i styrke,
   så de ikke konkurrerer med navnet. */
.system-list img {
    display: block;
    height: 1.375rem;
    width: auto;
    opacity: 0.68;
}

/* DanDomains logo har en "by teamblue"-underlinje inde i sit viewBox, så
   selve ordmærket fylder kun omkring 70 % af højden. Uden dette hak ville
   det se mindre ud end Shopifys ved samme pixelhøjde.
   Selektoren SKAL medtage img — .system-list img vejer tungere end en bar
   klasse og vandt ellers. */
.system-list img.logo-dandomain { height: 1.75rem; }

/* ── Portrættet ── */

/* Portrættet er ikke beskåret. Det ligger i sit fulde format og bløder ud
   til viewportens højre kant: gutteren plus den centreringsmargin .stage får
   når viewporten er bredere end 82rem. body har overflow-x: hidden, så
   100vw-udregningen ikke kan fremkalde en vandret scrollbar. */
.portrait {
    margin: 0 calc(-1 * (var(--gutter) + max(0px, (100vw - 82rem) / 2))) 0 0;
    position: relative;
    min-width: 0;
}

.portrait picture { display: block; }

/* Billedet er lyst — hvide skabe, lys væg, hvid trøje — på en næsten sort
   side. Uden dæmpning ligger det som en hvid plade ovenpå. sepia er det der
   gør at det læser varmt frem for koldt gråt mod den varme næsten-sorte.
   Fadet er en maske, ikke et gradientlag ovenpå: masken fjerner pixels, så
   billedet faktisk forsvinder ind i baggrunden uanset hvad der ligger bag.
   Ingen ramme — en kant og et fade udelukker hinanden. */
.portrait img {
    display: block;
    width: 100%;
    height: auto;
    filter: saturate(0.82) contrast(1.06) brightness(0.86) sepia(0.12);
    -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.4) 24%, #000 58%);
    mask-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.4) 24%, #000 58%);
}

/* Masken tager den vandrette side. Her blødes kun over- og underkant, så
   billedet ikke ender i to skarpe vandrette linjer.
   Ingen varm tone i dette lag: den ville også lægge sig over det gennemsigtige
   felt til venstre og efterlade en svag rav-film på baggrunden. Varmen ligger
   i filteret på billedet i stedet. */
.portrait::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    /* Fuld dækkraft helt ude ved kanten, ellers står der en skarp vandret
       linje hvor de lyse skabe møder baggrunden. Ink over ink er usynligt,
       så laget gør ingen skade over det gennemsigtige felt til venstre. */
    background:
        linear-gradient(to top, rgb(11, 10, 9), transparent 30%),
        linear-gradient(to bottom, rgb(11, 10, 9), transparent 26%);
}

@media (max-width: 56rem) {
    .stage {
        grid-template-columns: minmax(0, 1fr);
        gap: clamp(1.5rem, 4vh, 2.5rem);
    }

    /* Stablet layout: billedet går ud til begge kanter. Der er ingen "højre"
       at fade fra når det fylder hele bredden, så fadet vender nedad og
       teksten træder ud af billedet i stedet. */
    .portrait {
        order: -1;
        margin: 0 calc(-1 * var(--gutter));
    }

    .portrait img {
        -webkit-mask-image: linear-gradient(to bottom, #000 58%, transparent);
        mask-image: linear-gradient(to bottom, #000 58%, transparent);
    }

    .portrait::after {
        background: linear-gradient(to top, rgba(11, 10, 9, 0.35), transparent 34%);
    }
}

/* ── 404: samme scene, kun én spalte ── */

/* Samme venstre gutter som forsiden, så de to sider ikke hopper i forhold
   til hinanden når man rammer 404 og klikker videre. */
.stage-solo {
    grid-template-columns: minmax(0, 1fr);
    align-items: center;
}

/* ── Bundniveau ── */

::selection { background: var(--amber); color: var(--ink); }

a:focus-visible,
.linkedin:focus-visible {
    outline: 2px solid var(--amber);
    outline-offset: 4px;
    border-radius: 1px;
}

@media (prefers-reduced-motion: reduce) {
    .wash { animation: none; transform: translate3d(58vw, 5vh, 0) scale(1.1); }
    .topline,
    .name,
    .lead,
    .linkedin,
    .refs,
    .systems,
    .portrait { animation: none; }
    .linkedin,
    .linkedin-arrow { transition: none; }
}
