:root {
    --void: #0A0B0D;
    --void-2: #0E1014;
    --panel: #131620;
    --panel-2: #191D29;
    --line: #262B38;
    --line-2: #333A4A;

    --copper: #D98841;
    --copper-br: #F2A961;
    --copper-dp: #A85D2C;

    --ink: #F2F0EC;
    --ink-dim: #9BA2AE;
    --ink-faint: #5D6573;

    --danish: #C8102E;
    --danish-dark: #a10d26;

    --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    --disp: 'Space Grotesk', system-ui, sans-serif;
    --body: 'Inter', system-ui, sans-serif;

    /* Compatibility aliases - kept so inline styles in templates/JS
       (var(--gray-600), var(--red)) still resolve correctly. */
    --gray-50: var(--void);
    --gray-100: var(--line);
    --gray-300: var(--line-2);
    --gray-600: var(--ink-dim);
    --text: var(--ink);
    --red: var(--danish);
    --red-dark: var(--danish-dark);
    --green: #34D399;
}

* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: var(--body);
    background: var(--void);
    color: var(--ink);
    margin: 0;
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    background-image:
        linear-gradient(var(--line) 1px, transparent 1px),
        linear-gradient(90deg, var(--line) 1px, transparent 1px);
    background-size: 46px 46px;
    background-position: center top;
    background-attachment: fixed;
}

body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background: radial-gradient(120% 80% at 50% 0%, rgba(10, 11, 13, 0.55), var(--void) 60%);
}

a {
    color: inherit;
    text-decoration: none;
}

::selection {
    background: var(--copper);
    color: #1a1205;
}

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

.eyebrow {
    font-family: var(--mono);
    font-size: 11.5px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--copper);
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

.eyebrow::before {
    content: "";
    width: 22px;
    height: 1px;
    background: var(--copper);
    opacity: 0.7;
}

.hero .eyebrow::before {
    display: none;
}

.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    backdrop-filter: saturate(140%) blur(12px);
    background: rgba(10, 11, 13, 0.72);
    border-bottom: 1px solid transparent;
    transition: border-color 0.3s, background 0.3s;
}

.site-header.scrolled {
    border-bottom-color: var(--line);
    background: rgba(10, 11, 13, 0.9);
}

/* One width on every page. This used to take the page's own width class, so
   narrow pages rendered the header at 800px -- less than its contents need --
   and the action buttons wrapped to two and three lines. The header is chrome:
   it looks the same everywhere or it looks broken. */
.site-header__inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 1.5rem;
    height: 66px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
}

.site-header__links {
    display: flex;
    gap: 1.75rem;
    align-items: center;
    justify-content: center;
    flex: 1;
}

.site-header__links a {
    font-family: var(--mono);
    font-size: 12.5px;
    letter-spacing: 0.04em;
    color: var(--ink-dim);
    transition: color 0.2s;
}

.site-header__links a:hover {
    color: var(--ink);
}

/* The header drops its contents in priority order as it narrows, because the
   buttons no longer wrap to make room (see .site-header__actions .btn) - they
   would run off the edge instead. Measured against the real header: the brand
   and both buttons need ~540px, the Denmark tag another ~270, and these links
   another ~150 on top. Hence 1000 here and 880 for the tag.

   Both were set lower (900 and 560) when the buttons still wrapped, which left
   two windows - 901-1000 and 561-870 - where everything was displayed and did
   not fit. */
@media (max-width: 1000px) {
    .site-header__links {
        display: none;
    }
}

.site-footer {
    position: relative;
    z-index: 1;
    border-top: 1px solid var(--line);
    background: var(--void-2);
    margin-top: 3rem;
}

/* Matches the header -- chrome, not content, so the two brands sit on the same
   left edge whatever width the page between them is using. */
.site-footer__inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 1.5rem;
}

.foot__top {
    display: grid;
    grid-template-columns: 1.6fr 1fr 1.3fr;
    gap: 2.5rem;
    padding: 3.5rem 0 2.5rem;
}

.foot__about {
    color: var(--ink-dim);
    max-width: 36ch;
    margin: 1rem 0 1.2rem;
    font-size: 0.88rem;
}

.foot__id {
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--ink-dim);
    line-height: 1.9;
}

.foot__id .lab {
    color: var(--ink-faint);
    display: inline-block;
    width: 90px;
}

.foot__id a {
    color: var(--copper);
}

.site-footer h5 {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin: 0 0 1.1rem;
}

.site-footer ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.site-footer ul a {
    color: var(--ink-dim);
    font-size: 0.88rem;
    transition: color 0.15s;
}

.site-footer ul a:hover {
    color: var(--copper);
}

.foot__bar {
    border-top: 1px solid var(--line);
    padding: 1.4rem 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.9rem;
}

.foot__bar-lt {
    font-family: var(--mono);
    font-size: 0.72rem;
    color: var(--ink-faint);
    display: flex;
    gap: 1.4rem;
    flex-wrap: wrap;
}

.foot__bar-lt a:hover {
    color: var(--copper);
}

.foot__bar-rt {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--mono);
    font-size: 0.72rem;
    color: var(--ink-faint);
}

.flag-icon {
    width: 18px;
    height: 12px;
    border-radius: 2px;
}

@media (max-width: 900px) {
    .foot__top {
        grid-template-columns: 1fr 1fr;
    }
    .foot__bar {
        flex-direction: column;
        align-items: flex-start;
    }
}

@media (max-width: 560px) {
    .foot__top {
        grid-template-columns: 1fr;
    }
}

.brand {
    font-family: var(--disp);
    font-weight: 700;
    font-size: 1.4rem;
    letter-spacing: -0.02em;
    color: var(--ink);
    display: inline-flex;
    align-items: center;
    gap: 0;
}

.brand span {
    color: var(--danish);
}

.brand-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--copper);
    margin-left: 7px;
    align-self: flex-end;
    margin-bottom: 5px;
    box-shadow: 0 0 10px var(--copper);
    display: inline-block;
}

.page {
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem 1.5rem;
    position: relative;
    z-index: 1;
}

.card {
    background: linear-gradient(180deg, rgba(25, 29, 41, 0.5), rgba(19, 22, 32, 0.5));
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 2rem;
}

.configurator__col {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.details-card {
    background: var(--void-2);
    border: 1px solid var(--line);
    border-top: 3px solid var(--copper);
    border-radius: 14px;
    overflow: hidden;
}

.details-card__header {
    background: rgba(217, 136, 65, 0.06);
    border-bottom: 1px solid var(--line);
    color: var(--copper);
    padding: 1rem 2rem;
    font-family: var(--mono);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    font-weight: 500;
}

.details-card__body {
    padding: 2rem;
}

h1, h2, h3 {
    font-family: var(--disp);
    color: var(--ink);
    letter-spacing: -0.01em;
}

.flashes {
    list-style: none;
    margin: 0 0 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.flashes li {
    background: rgba(200, 16, 46, 0.08);
    border: 1px solid var(--danish);
    color: #ff8b96;
    padding: 0.75rem 1rem;
    border-radius: 8px;
}

.flashes li.success {
    background: rgba(52, 211, 153, 0.08);
    border-color: var(--green);
    color: var(--green);
}

label {
    display: block;
    font-family: var(--mono);
    font-weight: 500;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-dim);
    margin-bottom: 1.1rem;
}

input, select, textarea {
    width: 100%;
    margin-top: 0.5rem;
    padding: 0.7rem 0.8rem;
    background: var(--panel-2);
    border: 1px solid var(--line-2);
    border-radius: 8px;
    font-size: 1rem;
    font-family: var(--mono);
    color: var(--ink);
    transition: 0.15s;
}

input::placeholder, textarea::placeholder {
    color: var(--ink-faint);
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--copper);
    background: #1c2130;
}

input[readonly], select:disabled {
    background: var(--line);
    color: var(--ink-faint);
    border-color: var(--line-2);
    cursor: not-allowed;
}

input[readonly]:focus, select:disabled:focus {
    border-color: var(--line-2);
    background: var(--line);
}

.seg button:disabled, button:disabled {
    cursor: not-allowed;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input[type="number"] {
    -moz-appearance: textfield;
}

select {
    appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2 4l4 4 4-4' stroke='%23D98841' stroke-width='1.4' fill='none' stroke-linecap='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: 38px;
    cursor: pointer;
}

input[type="file"] {
    padding: 0.5rem;
    cursor: pointer;
}

input[type="file"]::file-selector-button,
input[type="file"]::-webkit-file-upload-button {
    font-family: var(--mono);
    background: linear-gradient(180deg, var(--copper-br), var(--copper));
    color: #1a1205;
    border: none;
    padding: 0.75rem 1.4rem;
    border-radius: 9px;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: 0.2s;
    margin-right: 0.75rem;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25) inset, 0 8px 24px -8px rgba(217, 136, 65, 0.55);
}

input[type="file"]::file-selector-button:hover,
input[type="file"]::-webkit-file-upload-button:hover {
    filter: brightness(1.06);
    color: #1a1205;
}

.btn, button {
    font-family: var(--mono);
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--line-2);
    padding: 0.75rem 1.4rem;
    border-radius: 9px;
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
    transition: 0.2s;
}

.btn:hover, button:hover {
    border-color: var(--copper);
    color: var(--copper);
}

.btn:disabled, button:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    filter: grayscale(0.4);
}

.btn:disabled:hover, button:disabled:hover {
    border-color: var(--line-2);
    color: var(--ink);
}

.btn--cu {
    background: linear-gradient(180deg, var(--copper-br), var(--copper));
    color: #1a1205;
    border: none;
    font-weight: 600;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25) inset, 0 8px 24px -8px rgba(217, 136, 65, 0.55);
}

.btn--cu:hover {
    filter: brightness(1.06);
    color: #1a1205;
    border: none;
}

.btn--lg {
    padding: 0.95rem 1.6rem;
    font-size: 0.95rem;
}

.btn--ghost {
    background: transparent;
    border: 1px solid var(--line-2);
}

.btn--ghost:hover {
    border-color: var(--copper);
}

table {
    width: 100%;
    border-collapse: collapse;
}

th, td {
    text-align: left;
    padding: 0.6rem 0.7rem;
    border-bottom: 1px solid var(--line);
}

th {
    color: var(--ink-dim);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* Order history (account dashboard). Inherits the table rules above - this
   only stops the per-row action button from filling its cell, and keeps the
   board/date columns from wrapping mid-value on a narrow viewport (the table
   scrolls horizontally instead, see the wrapper in account_dashboard.html). */
.order-history td {
    white-space: nowrap;
    vertical-align: middle;
}

.order-history td .btn {
    padding: 0.35rem 0.7rem;
    font-size: 0.85rem;
}

/* ---------- Configurator (instant quote) ---------- */

.page--wide {
    max-width: 1180px;
}

.sec {
    padding: 5rem 0;
}

.sec__head {
    max-width: 62ch;
    margin-bottom: 3rem;
}

.sec__head h2 {
    font-weight: 600;
    letter-spacing: -0.025em;
    font-size: clamp(1.9rem, 4vw, 2.7rem);
    line-height: 1.05;
    margin: 1rem 0 0;
}

/* ---------- Rework ---------- */

.rework__body {
    max-width: 62ch;
}

.rework__body p {
    color: var(--ink-dim);
    line-height: 1.7;
    margin: 0 0 1.1rem;
}

.rework__cta {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
    margin-top: 2rem;
}

/* The address is here to be copied as much as clicked - someone forwarding a
   board to a colleague needs to read it, not just follow a mailto. */
.rework__contact {
    font-family: var(--mono);
    font-size: 0.9rem;
    color: var(--ink-dim);
    user-select: all;
}

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

.hero {
    position: relative;
    overflow: hidden;
    border-bottom: 1px solid var(--line);
    width: 100vw;
    left: 50%;
    margin-left: -50vw;
    margin-top: -2rem;
}

.hero__traces {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    opacity: 0.55;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
}

.tp {
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
    animation: draw 2.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

.tp:nth-of-type(2) { animation-delay: 0.2s; }
.tp:nth-of-type(3) { animation-delay: 0.4s; }
.tp:nth-of-type(4) { animation-delay: 0.6s; }
.tp:nth-of-type(5) { animation-delay: 0.8s; }

.pads use {
    opacity: 0;
    animation: popPad 0.5s ease forwards 1.6s;
}

@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes popPad { from { opacity: 0; } to { opacity: 1; } }

.hero__in {
    position: relative;
    z-index: 2;
    padding: 6.5rem 1.5rem 4.4rem;
    max-width: 1180px;
    margin: 0 auto;
}

.site-header__actions {
    display: flex;
    align-items: center;
    gap: 1rem;
}

/* Belt and braces on top of the fixed header width above: a button label is
   two or three words and must stay on one line, so the buttons are the same
   size on every page. Without this they silently re-wrap the moment anything
   else in the header grows. */
.site-header__actions .btn {
    white-space: nowrap;
    flex: none;
}

/* Phones. Below about 500px the brand and both buttons genuinely do not fit at
   full size, and since they can no longer wrap they would run off the edge
   instead. Scaled down rather than dropped: the footer carries no login link,
   so hiding "Log in" here would leave no way in on a phone.

   Applies at every width to every page alike, which is the property that
   matters - the buttons must not change between the order form and the order
   status page, and they don't. */
@media (max-width: 560px) {
    .site-header__inner {
        /* 1.5rem each side is a third of a 320px screen. */
        padding: 0 0.75rem;
        gap: 0.75rem;
    }
    .site-header__actions {
        gap: 0.5rem;
    }
    .site-header__actions .btn {
        padding: 0.6rem 0.85rem;
        font-size: 0.85rem;
    }
}

.dk-tag {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    font-family: var(--mono);
    font-size: 13px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-dim);
    border: 1px solid var(--line);
    border-radius: 40px;
    padding: 9px 18px 9px 10px;
    background: rgba(19, 22, 32, 0.6);
    flex: none;
}

.dk-tag .flag-icon {
    width: 26px;
    height: 18px;
}

.hero h1 {
    font-weight: 700;
    line-height: 0.96;
    letter-spacing: -0.035em;
    font-size: clamp(3.1rem, 8.5vw, 6.4rem);
    margin: 18px 0 0;
    max-width: 14ch;
}

.hero h1 .em {
    color: var(--copper);
    position: relative;
}

.hero p.lead {
    font-size: clamp(1.05rem, 2vw, 1.28rem);
    color: var(--ink-dim);
    max-width: 54ch;
    margin: 26px 0 0;
}

.hero p.lead b {
    color: var(--ink);
    font-weight: 600;
}

.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 1.5rem;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--mono);
    font-size: 12.5px;
    color: var(--ink-dim);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 9px 14px;
    background: rgba(19, 22, 32, 0.45);
}

.chip svg {
    width: 15px;
    height: 15px;
    color: var(--copper);
    flex: none;
}

.hero__cta {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 2.2rem;
}

@media (max-width: 920px) {
    .hero__in {
        padding: 3.5rem 1.5rem 2.5rem;
    }
}

/* Next to go after the nav links - decorative, and the widest single item in
   the header. See the note on the 1000px breakpoint above. */
@media (max-width: 880px) {
    .dk-tag {
        display: none;
    }
}

.ticker {
    border-top: 1px solid var(--line);
    background: rgba(14, 16, 20, 0.6);
    position: relative;
    z-index: 2;
    overflow: hidden;
}

.ticker__row {
    display: flex;
    gap: 0;
    white-space: nowrap;
    animation: slide 34s linear infinite;
}

.ticker__row span {
    font-family: var(--mono);
    font-size: 12px;
    letter-spacing: 0.06em;
    color: var(--ink-faint);
    padding: 13px 30px;
    display: inline-flex;
    align-items: center;
    gap: 30px;
    text-transform: uppercase;
}

.ticker__row span::after {
    content: "◇";
    color: var(--copper);
    opacity: 0.6;
}

@keyframes slide {
    to { transform: translateX(-50%); }
}

/* reveal-on-scroll */
.rv {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.rv.in {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    * {
        animation: none !important;
        transition: none !important;
        scroll-behavior: auto;
    }
    .rv {
        opacity: 1;
        transform: none;
    }
    .tp {
        stroke-dashoffset: 0 !important;
    }
    .pads use {
        opacity: 1 !important;
    }
}

/* ---------- Process ---------- */

.proc__track {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 0;
    position: relative;
    margin-top: 0.5rem;
}

.proc__line {
    position: absolute;
    top: 31px;
    left: 7%;
    right: 7%;
    height: 2px;
    background: repeating-linear-gradient(90deg, var(--copper) 0 10px, transparent 10px 18px);
    opacity: 0.5;
}

.step {
    position: relative;
    text-align: center;
    padding: 0 12px;
}

.step__node {
    width: 64px;
    height: 64px;
    border-radius: 14px;
    margin: 0 auto 18px;
    display: grid;
    place-items: center;
    background: var(--panel);
    border: 1px solid var(--line-2);
    position: relative;
    z-index: 2;
    transition: 0.25s;
    color: var(--copper);
}

.step__node svg {
    width: 26px;
    height: 26px;
}

.step:hover .step__node {
    border-color: var(--copper);
    transform: translateY(-3px);
    box-shadow: 0 12px 30px -12px rgba(217, 136, 65, 0.5);
}

.step__no {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--copper);
    letter-spacing: 0.1em;
    display: block;
    margin-bottom: 5px;
}

.step h3 {
    font-weight: 500;
    font-size: 1.02rem;
    margin: 0 0 5px;
}

.step small {
    color: var(--ink-faint);
    font-size: 0.83rem;
    line-height: 1.4;
    display: block;
}

@media (max-width: 920px) {
    .proc__track {
        grid-template-columns: repeat(2, 1fr);
        gap: 2rem 0.75rem;
    }
    .proc__line {
        display: none;
    }
}

/* ---------- Form / configurator ---------- */

.configurator {
    display: grid;
    grid-template-columns: 1fr 360px;
    gap: 1.75rem;
    /* No align-items: start here on purpose - the aside needs to stretch to
       the full height of the (taller) left column so its sticky child has
       room to travel with the scroll instead of being stuck at its initial
       position once the short aside box ends. */
}

.configurator .lede {
    grid-column: 1 / -1;
    margin-bottom: 1rem;
}

.configurator .lede h2 {
    margin: 0.75rem 0 0;
}

.configurator .lede p {
    color: var(--ink-dim);
    max-width: 60ch;
    margin-top: 0.75rem;
}

.field-note {
    font-size: 0.8rem;
    color: var(--ink-dim);
    margin: 0.4rem 0 0;
}

fieldset.section {
    border: none;
    margin: 0;
    padding: 1.75rem 0;
}

fieldset.section + fieldset.section {
    border-top: 1px solid var(--line);
}

.card > fieldset.section:first-child {
    padding-top: 0;
}

.card > fieldset.section:last-child {
    padding-bottom: 0;
}

fieldset.section legend {
    font-family: var(--mono);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--copper);
    font-weight: 500;
    padding: 0 0.4rem;
}

.config-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem 1.25rem;
    margin-top: 1rem;
}

.config-row.one {
    grid-template-columns: 1fr;
}

.field-label {
    display: block;
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-dim);
    font-weight: 500;
    margin-bottom: 0.6rem;
}

.dims {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.dims input {
    width: auto;
    flex: 1;
    margin-top: 0;
}

.dims .times {
    color: var(--ink-faint);
    font-weight: 600;
}

.dims .unit {
    color: var(--ink-faint);
    font-size: 0.85rem;
}

.seg {
    display: inline-flex;
    flex-wrap: wrap;
    background: var(--panel-2);
    border: 1px solid var(--line-2);
    border-radius: 9px;
    padding: 4px;
    gap: 4px;
}

.seg button {
    font-family: var(--mono);
    background: transparent;
    color: var(--ink-dim);
    border: none;
    border-radius: 7px;
    padding: 0.55rem 1rem;
    font-size: 0.85rem;
    font-weight: 500;
    cursor: pointer;
}

.seg button:hover {
    color: var(--ink);
    border: none;
}

.seg button[aria-pressed="true"] {
    background: var(--copper);
    color: #1a1205;
    font-weight: 600;
}

.copper-layers {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.copper-layer-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
}

.copper-layer-row .copper-layer-label {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.05em;
    color: var(--ink-dim);
    white-space: nowrap;
}

.copper-layer-row .seg {
    padding: 2px;
    gap: 2px;
}

.copper-layer-row .seg button {
    padding: 0.35rem 0.6rem;
    font-size: 0.78rem;
}

.swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.swatch {
    width: 40px;
    height: 40px;
    border-radius: 9px;
    border: 2px solid var(--line-2);
    cursor: pointer;
    background: var(--c);
    position: relative;
}

.swatch:hover {
    transform: translateY(-2px);
}

.swatch[aria-pressed="true"] {
    border-color: var(--copper);
    box-shadow: 0 0 0 3px rgba(217, 136, 65, 0.18);
}

.viz {
    display: grid;
    grid-template-columns: 1fr 1.25fr;
    gap: 1.25rem;
    margin-top: 1rem;
    align-items: stretch;
}

.viz__cell {
    background: var(--void-2);
    border: 1px solid var(--line);
    border-radius: 9px;
    padding: 1.1rem;
}

.viz__cell h4 {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin: 0 0 1rem;
    display: flex;
    justify-content: space-between;
}

.viz__cell h4 b {
    color: var(--copper);
    font-weight: 500;
}

.board-stage {
    display: grid;
    place-items: center;
    min-height: 160px;
}

.board {
    position: relative;
    border-radius: 6px;
    border: 1px solid rgba(0, 0, 0, 0.4);
    background-image: radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.08) 1px, transparent 1.4px);
    background-size: 11px 11px;
    box-shadow: 0 14px 34px -16px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.04) inset;
    transition: width 0.3s, height 0.3s, background-color 0.25s;
}

.board .pad {
    position: absolute;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--copper);
    box-shadow: 0 0 6px rgba(217, 136, 65, 0.7);
}

.board .trace {
    position: absolute;
    background: var(--copper);
    opacity: 0.55;
    height: 2px;
    border-radius: 2px;
}

.board .hole {
    position: absolute;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--void);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25);
}

.stack {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.layer {
    display: flex;
    align-items: center;
    gap: 12px;
    font-family: var(--mono);
    font-size: 10px;
    color: var(--ink-faint);
}

.layer .bar {
    height: 11px;
    border-radius: 2px;
    flex: 1;
    transition: 0.25s;
}

.layer .lbl {
    width: 78px;
    text-align: right;
    letter-spacing: 0.05em;
    white-space: nowrap;
}

.bar-mask {
    background: var(--mask, #1f6b3a);
}

.bar-cu {
    background: linear-gradient(90deg, var(--copper-dp), var(--copper));
    height: 7px !important;
}

.bar-core {
    background: repeating-linear-gradient(45deg, #2c2a1c 0 6px, #34311f 6px 12px);
}

.bar-silk {
    background: #d9d6cf;
    height: 4px !important;
}

@media (max-width: 700px) {
    .viz {
        grid-template-columns: 1fr;
    }
}

.gerber-preview {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
    margin-top: 1rem;
}

.gerber-preview__side {
    min-width: 0;
}

/* Carries the frame (margin/border/background) that used to sit on the img
   itself, so the img and the placement overlay can share one identical box
   - see .placement-overlay below for why that matters. */
.gerber-preview__img-wrap {
    position: relative;
    margin-top: 0.4rem;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: #0a0b0d;
    overflow: hidden;
}

/* No min-height and no object-fit, deliberately. Both existed to keep the
   box from collapsing before the image loads, but together they letterboxed
   the image inside a taller element - and the overlay above then ran its
   OWN independent fit-and-centre against a slightly different box (offset
   by the margin, inset by the border). Two centring calculations that only
   agree by luck, which is what put placement markers visibly off their
   pads. Letting the img size to its natural aspect makes the wrapper's
   content box exactly the image, so the overlay's inset: 0 is an exact
   match by construction rather than by coincidence. */
.gerber-preview__side img {
    display: block;
    width: 100%;
    height: auto;
}

/* Drawn in the exact same board-outline coordinate space as the image
   beneath it (see renderPlacementOverlay in configurator.js). inset: 0
   against the wrapper's content box - which the img exactly fills - so the
   SVG viewBox and the PNG cover identical pixels and no preserveAspectRatio
   letterboxing can creep in on either side. pointer-events are disabled so
   it never blocks interacting with anything else. */
.placement-overlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

/* Routine, non-alarming per-part checklist - unlike .exclusion-list (a
   BOM-mismatch warning, red-themed on purpose), nothing is wrong here by
   default, so it stays in the form's normal neutral palette. */
.placement-list {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0.5rem 0.75rem;
    background: var(--panel-2);
    border: 1px solid var(--line-2);
    border-radius: 8px;
    display: none;
    max-height: 260px;
    overflow-y: auto;
}

.placement-list:empty {
    display: none;
}

.placement-list li {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.25rem 0;
    font-size: 0.85rem;
    color: var(--ink-dim);
}

.placement-list input[type="checkbox"] {
    width: auto;
    margin: 0.15rem 0 0;
}

/* While a real Gerber render is showing, the board-preview cell needs much
   more room than the synthetic CSS mockup it replaces - span the whole
   configurator width instead of sharing half of it with the cross-section,
   which just gets pushed below. */
.viz--gerber-active {
    grid-template-columns: 1fr;
}

.viz--gerber-active .viz__cell:first-child {
    order: -1;
}

.switch-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.4rem 0;
}

.switch-row .field-label {
    margin-bottom: 0;
}

.switch {
    position: relative;
    width: 42px;
    height: 24px;
    flex: none;
}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
    position: absolute;
}

.switch .track {
    position: absolute;
    inset: 0;
    background: var(--panel-2);
    border: 1px solid var(--line-2);
    border-radius: 20px;
    cursor: pointer;
    transition: 0.15s;
}

.switch .track::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--ink);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
    transition: 0.15s;
}

.switch input:checked + .track {
    background: var(--copper);
    border-color: var(--copper);
}

.switch input:checked + .track::after {
    transform: translateX(18px);
    background: #1a1205;
}

.quote-card {
    position: sticky;
    top: 5.5rem;
    background: linear-gradient(180deg, rgba(25, 29, 41, 0.5), rgba(19, 22, 32, 0.5));
    border: 1px solid var(--line);
    border-radius: 14px;
    overflow: hidden;
}

.quote-card__header {
    background: rgba(217, 136, 65, 0.06);
    border-bottom: 1px solid var(--line);
    color: var(--copper);
    padding: 1rem 1.25rem;
    font-family: var(--mono);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    font-weight: 500;
}

.quote-card__body {
    padding: 1.5rem 1.375rem;
}

.price {
    padding: 6px 0 2px;
}

.price__big {
    font-family: var(--disp);
    font-weight: 700;
    letter-spacing: -0.02em;
    font-size: 2.9rem;
    line-height: 1;
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.price__big .cur {
    font-family: var(--mono);
    font-size: 1rem;
    color: var(--ink-dim);
    font-weight: 500;
}

.price__sub {
    font-family: var(--mono);
    font-size: 12.5px;
    color: var(--ink-dim);
    margin-top: 8px;
}

.price__sub b {
    color: var(--copper);
}

.items {
    margin-top: 20px;
    border-top: 1px solid var(--line);
    padding-top: 16px;
    display: flex;
    flex-direction: column;
    gap: 11px;
}

.item {
    display: flex;
    justify-content: space-between;
    font-family: var(--mono);
    font-size: 12.5px;
    color: var(--ink-dim);
}

.item span:last-child {
    color: var(--ink);
}

.item.muted span:last-child {
    color: var(--ink-faint);
}

.item.total {
    border-top: 1px solid var(--line);
    margin-top: 6px;
    padding-top: 14px;
    font-size: 14px;
}

.item.total span {
    color: var(--ink);
    font-weight: 600;
}

.item.total span:last-child {
    color: var(--copper);
}

.note {
    font-family: var(--mono);
    font-size: 11px;
    line-height: 1.6;
    color: var(--ink-faint);
    margin-top: 18px;
    border-left: 2px solid var(--copper);
    padding-left: 12px;
}

.quote-card .btn--cu {
    width: 100%;
    justify-content: center;
    margin-top: 20px;
    padding: 15px;
}

.quote-card .btn--cu:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    filter: grayscale(0.4);
}

@media (max-width: 920px) {
    .configurator {
        grid-template-columns: 1fr;
    }

    .quote-card {
        position: static;
    }
}

.validation-banner {
    background: rgba(200, 16, 46, 0.08);
    border: 1px solid var(--danish);
    color: #ff8b96;
    padding: 1rem 1.25rem;
    border-radius: 8px;
    font-weight: 600;
    margin: 0.75rem 0 0;
}

.validation-banner ul {
    margin: 0.5rem 0 0;
    padding-left: 1.25rem;
    font-weight: 500;
}

.field-invalid {
    border-color: var(--danish) !important;
    box-shadow: 0 0 0 2px rgba(200, 16, 46, 0.18);
}

.exclusion-list {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0.75rem 1rem;
    background: rgba(200, 16, 46, 0.08);
    border: 1px solid var(--danish);
    border-radius: 8px;
    display: none;
}

.exclusion-list:empty {
    display: none;
}

.exclusion-list li {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.25rem 0;
    font-size: 0.85rem;
    color: #ff8b96;
}

.exclusion-list input[type="checkbox"] {
    width: auto;
    margin: 0.15rem 0 0;
}

#consigned-options {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.8rem;
    padding: 0.75rem 0.9rem;
    background: var(--line);
    border: 1px solid var(--line-2);
    border-radius: 8px;
}


.price-spinner {
    display: inline-block;
    width: 32px;
    height: 32px;
    border: 3px solid var(--line-2);
    border-top-color: var(--copper);
    border-radius: 50%;
    animation: price-spin 0.7s linear infinite;
    vertical-align: middle;
}

.price-spinner[hidden] {
    display: none;
}

@keyframes price-spin { to { transform: rotate(360deg); } }

.file-list {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.file-list:empty {
    display: none;
}

.file-list li {
    background: var(--panel-2);
    border: 1px solid var(--line-2);
    border-radius: 6px;
    padding: 0.3rem 0.5rem;
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--ink-dim);
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.file-remove {
    background: none;
    color: var(--ink-faint);
    border: none;
    padding: 0;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.file-remove:hover {
    background: none;
    border: none;
    color: var(--danish);
}


/* ---------- delivery (PostNord shipping options + parcel shop picker) ---------- */

.ship-option {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.65rem 0.8rem;
    margin-top: 0.5rem;
    background: var(--panel-2);
    border: 1px solid var(--line-2);
    border-radius: 8px;
    cursor: pointer;
}

.ship-option:hover {
    border-color: var(--copper-dp);
}

.ship-option.is-selected {
    border-color: var(--copper);
    background: rgba(217, 136, 65, 0.08);
}

.ship-option input[type="radio"] {
    width: auto;
    margin: 0.2rem 0 0;
    flex: none;
}

.ship-option__body {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 1;
    min-width: 0;
}

.ship-option__top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    font-size: 0.92rem;
}

.ship-option__price {
    font-family: var(--mono);
    color: var(--copper-br);
    white-space: nowrap;
}

.ship-option__meta {
    font-size: 0.78rem;
    color: var(--ink-dim);
}

.ship-option__flag {
    font-size: 0.78rem;
    color: var(--orange, #d99a41);
}

.service-point-list {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    /* Eight shops is a lot of near-identical cards - cap the height so the
       delivery options underneath stay reachable without a long scroll. */
    max-height: 22rem;
    overflow-y: auto;
}

.service-point label {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.55rem 0.7rem;
    background: var(--panel-2);
    border: 1px solid var(--line-2);
    border-radius: 8px;
    cursor: pointer;
    margin: 0;
}

.service-point label:hover {
    border-color: var(--copper-dp);
}

.service-point.is-selected label {
    border-color: var(--copper);
    background: rgba(217, 136, 65, 0.08);
}

.service-point input[type="radio"] {
    width: auto;
    margin: 0.2rem 0 0;
    flex: none;
}

.service-point__body {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.service-point__meta {
    font-size: 0.78rem;
    color: var(--ink-dim);
}

/* ---------- Edit Part dialog (static/js/part_editor.js) ---------- */
/* The only modal on the site. Native <dialog>, so Escape, focus trapping and
   inertness of the page behind it are the browser's job rather than ours. */
.part-editor {
    width: min(30rem, calc(100vw - 2rem));
    padding: 1.5rem;
    background: var(--panel);
    border: 1px solid var(--line-2);
    border-radius: 12px;
    color: var(--ink);
}

.part-editor::backdrop {
    background: rgba(10, 11, 13, 0.72);
}

.part-editor__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.part-editor__head h3 {
    margin: 0;
    font-family: var(--disp);
    font-size: 1.15rem;
    /* An MPN in the title can be long enough to shove the close button off
       the edge; let it wrap rather than overflow the dialog. */
    overflow-wrap: anywhere;
}

.part-editor__close {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    padding: 0;
    font-size: 1.4rem;
    line-height: 1;
    background: none;
    border: none;
    color: var(--ink-dim);
    cursor: pointer;
    transition: 0.15s;
}

.part-editor__close:hover {
    color: var(--ink);
}

/* Matches the red asterisk convention of a required field. */
.part-editor__req {
    color: var(--danish);
}

.part-editor__error {
    color: var(--danish);
}

.part-editor__warn {
    color: var(--copper);
}

.part-editor__actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
    margin-top: 1.5rem;
}

.part-editor__btn {
    padding: 0.6rem 1.4rem;
    background: none;
    border: 1px solid var(--line-2);
    border-radius: 999px;
    font-family: var(--body);
    font-size: 0.9rem;
    color: var(--ink-dim);
    cursor: pointer;
    transition: 0.15s;
}

.part-editor__btn:hover {
    color: var(--ink);
    border-color: var(--ink-faint);
}

.part-editor__btn--primary {
    background: var(--copper);
    border-color: var(--copper);
    color: var(--void);
    font-weight: 600;
}

.part-editor__btn--primary:hover {
    background: var(--copper-br);
    border-color: var(--copper-br);
    color: var(--void);
}

.part-editor__btn--primary:disabled {
    background: var(--line);
    border-color: var(--line-2);
    color: var(--ink-faint);
}

/* ---------- parts availability row controls ---------- */
.part-edit-btn {
    width: auto;
    margin-left: 0.4rem;
    padding: 0 0.3rem;
    background: none;
    border: none;
    font-size: 0.85rem;
    line-height: 1;
    color: inherit;
    opacity: 0.75;
    cursor: pointer;
    transition: 0.15s;
}

.part-edit-btn:hover {
    opacity: 1;
}

.part-row__controls {
    margin-top: 0.2rem;
    margin-left: 1.6rem;
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

/* Both types, not just checkboxes. The global `input` rule above sets
   width: 100%, which on a flex row makes each control a 269px-wide item that
   squeezes the labels beside it to min-content - "Danish PCB buys" wrapped to
   three lines, with the radio dot centred in a wide padded box far from its
   own text. The radio half of this was missing; .ship-option and
   .service-point already carry the same override. */
.part-row__controls input[type="checkbox"],
.part-row__controls input[type="radio"] {
    width: auto;
    margin: 0;
    cursor: pointer;
    flex-shrink: 0;
}

/* Overrides the global `label` rule, which is written for form field labels
   (block, uppercase, mono, 1.1rem bottom margin). These sit inline next to a
   checkbox in a sentence, so every one of those has to be undone - without
   it "I'll supply 5 x ESP32-C3FH4 component" renders as shouty mono caps. */
.part-row__controls label {
    display: inline;
    margin-bottom: 0;
    font-family: var(--body);
    font-size: 0.78rem;
    font-weight: 400;
    letter-spacing: normal;
    text-transform: none;
    color: var(--ink-dim);
    cursor: pointer;
}

/* One radio and its own text, as a single unit. The row used to be four
   siblings (radio, label, radio, label) under one uniform gap, so a label sat
   exactly as close to the *next* radio as to its own and neither pair read as
   a choice. Specificity has to beat `.part-row__controls label` above, which
   sets display:inline - two classes beats one class plus an element. */
.part-row__controls .part-row__choice {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
}

/* Tight inside a pair (above), wide between them. Wrapping is per choice, so
   a narrow screen drops the second option onto its own line whole rather than
   splitting one mid-phrase. */
.part-row__sourcing {
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
}

.part-row__was {
    font-size: 0.75rem;
    color: var(--ink-faint);
    margin-left: 0.35rem;
}

/* "(optional)" beside a field label - same line, deliberately quieter than
   the label itself so it reads as a qualifier rather than part of the name. */
.field-optional {
    text-transform: none;
    letter-spacing: normal;
    color: var(--ink-faint);
    font-weight: 400;
}

/* --- Order stage timeline (templates/_stage_timeline.html) ---------------
   A vertical list of the seven ORDER_STAGES, with the reached ones dated and
   the rest dimmed. The connecting line is drawn as a border on each step
   rather than one absolutely-positioned rule, so it can't fall out of
   alignment when a step wraps to two lines or carries a description. */
.stage-timeline {
    list-style: none;
    margin: 0.75rem 0 1.25rem;
    padding: 0;
}

.stage-timeline__step {
    position: relative;
    display: flex;
    gap: 0.85rem;
    padding: 0 0 1rem 0;
}

/* The line runs from each marker down to the next, so the last step must not
   draw one - it would hang below the final marker pointing at nothing. */
.stage-timeline__step::before {
    content: "";
    position: absolute;
    left: 0.3rem;
    top: 1rem;
    bottom: 0;
    width: 2px;
    background: var(--line-2);
}

.stage-timeline__step:last-child {
    padding-bottom: 0;
}

.stage-timeline__step:last-child::before {
    display: none;
}

.stage-timeline__marker {
    flex: 0 0 auto;
    width: 0.7rem;
    height: 0.7rem;
    margin-top: 0.3rem;
    border-radius: 50%;
    border: 2px solid var(--line-2);
    background: var(--void);
    z-index: 1;
}

.stage-timeline__body {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 0.6rem;
}

.stage-timeline__label {
    font-weight: 600;
}

.stage-timeline__date {
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--ink-dim);
}

/* One line under the current step only, so the timeline reads as a status
   rather than a glossary of every stage at once. */
.stage-timeline__note {
    flex-basis: 100%;
    margin: 0.15rem 0 0;
    font-size: 0.85rem;
    color: var(--ink-dim);
}

.stage-timeline__step--done .stage-timeline__marker {
    background: var(--green);
    border-color: var(--green);
}

.stage-timeline__step--done .stage-timeline__label {
    color: var(--ink-dim);
    font-weight: 400;
}

/* The one step the eye should land on: filled in the brand colour, with a
   halo so it still reads as "here" at a glance on a long list. */
.stage-timeline__step--current .stage-timeline__marker {
    background: var(--copper);
    border-color: var(--copper);
    box-shadow: 0 0 0 3px rgba(217, 136, 65, 0.25);
}

.stage-timeline__step--current .stage-timeline__label {
    color: var(--copper-br);
}

.stage-timeline__step--upcoming .stage-timeline__label,
.stage-timeline__step--upcoming .stage-timeline__date {
    color: var(--ink-faint);
}

/* A stage the order reached and has since been moved back from. Struck through
   rather than removed: the date is real history, and a step that quietly lost
   its date would look like a rendering fault. The qualifier beside it is what
   actually explains the row - the strike alone could read as a styling slip. */
.stage-timeline__date--superseded {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.stage-timeline__revised {
    font-family: var(--mono);
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-faint);
    border: 1px solid var(--line);
    border-radius: 4px;
    padding: 1px 5px;
    margin-left: 0.4rem;
    white-space: nowrap;
}

/* --- Placement overlay colour key (PlacementView.legendHtml) -------------
   Sits under the board preview on both the order form and the order-status
   page. Wraps rather than scrolls: it's four short items, and on a narrow
   screen a second line reads better than a cut-off one. */
.placement-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    margin: 0.5rem 0 0;
    font-size: 0.78rem;
    color: var(--ink-dim);
}

.placement-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

/* The swatch colour is set inline from the same constant the marker is drawn
   with - deliberately not duplicated here, where it could drift. */
.placement-legend__dot {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 2px;
    flex: 0 0 auto;
}
