﻿/* ---------------------------------------------------------------------------
   Traad design system.
   Tokens lifted from the reference marketplace so the two sites read as one brand:
   terracotta brown #a85b35 and cream #f9e7d7 from the Traad mark as the primary colour,
   1056px content width and 6/8px spacing unit. Radii are ours: 8px buttons, 10px imagery.
--------------------------------------------------------------------------- */

:root {
    --colorWhite: #fff;
    --colorGrey50: #fafafa;
    --colorGrey100: #e5e5e6;
    --colorGrey200: #cacace;
    --colorGrey300: #b0b0b5;
    --colorGrey400: #96969c;
    --colorGrey500: #7c7c83;
    --colorGrey600: #636369;
    --colorGrey700: #4a4a4f;
    --colorGrey800: #313135;
    --colorGrey900: #19191a;

    /* Brand: the terracotta brown and cream from the Traad mark. This is the primary colour —
       it drives action buttons, links, accents, borders and focus rings.
       Note the ...Light / ...Dark naming is inherited from the reference marketplace, where
       "Light" is the *darker* hover shade. Kept as-is so the usages below stay readable. */
    --brandBrown: #a85b35;
    --brandBrownDark: #8a4728;
    --brandBrownSoft: #c57a50;
    --brandCream: #f9e7d7;

    --marketplaceColor: var(--brandBrown);
    --marketplaceColorLight: var(--brandBrownDark);
    --marketplaceColorDark: var(--brandBrownSoft);

    --colorPrimaryButton: var(--brandBrown);
    --colorPrimaryButtonDark: var(--brandBrownDark);
    --colorPrimaryButtonLight: var(--brandBrownSoft);

    /* Warm borders. Strong for interactive edges (inputs, secondary buttons, chips, pager),
       subtle for panel and table rules so pages do not read as boxed-in. */
    --colorBorder: #dcc3ae;
    --colorBorderSubtle: #efe1d5;

    /* Status colours stay semantic rather than brand-tinted: a "Betalt" badge should read as
       success, not as brand. */
    --colorSuccess: #138041;
    --colorSuccessDark: #0d542a;
    --colorSuccessSubtle: #f0fff6;
    --colorFail: #e7000b;
    --colorFailSubtle: #fff0f0;
    --colorAttention: #fa0;
    --colorAttentionDark: #b25900;
    --colorAttentionSubtle: #fff7f0;

    /* Aptos first, then the closest thing each platform already has. Aptos is Microsoft's font and
       ships with Microsoft 365 and current Windows — it is not a free webfont, so it cannot be
       self-hosted or pulled from a CDN without a licence. Visitors who have it see it; the rest
       fall through to Segoe UI on Windows, the system face on macOS/iOS, then Inter and Arial. */
    --fontFamily: "Aptos", "Segoe UI Variable Text", "Segoe UI", -apple-system, BlinkMacSystemFont, "Inter", Helvetica, Arial, sans-serif;
    --fontWeightMedium: 500;
    --fontWeightSemiBold: 600;
    --fontWeightBold: 700;

    --contentMaxWidth: 1056px;
    --contentMaxWidthPages: 1120px;
    --spacingUnit: 6px;
    --spacingUnitDesktop: 8px;

    --borderRadius: 2px;
    --borderRadiusMedium: 4px;

    /* Softer corners for the two things people actually click and look at. Two image sizes because
       a fixed radius reads as more rounded the smaller the surface: 10px on a card, 8px on a 56-78px
       thumbnail. Panels, inputs and alerts stay on --borderRadiusMedium. */
    --borderRadiusButton: 8px;
    --borderRadiusImage: 10px;
    --borderRadiusImageSmall: 8px;

    --boxShadow: 0 2px 4px 0 #0000001a;
    --boxShadowLight: 0 2px 4px 0 #0000000d;
    --boxShadowButton: 0 4px 8px 0 #0000001a;
    --boxShadowListingCard: 0 0 50px 0 #0000001a;
    --boxShadowPopup: 0 8px 16px 0 #0000004d;

    --topbarHeight: 60px;
    --topbarHeightDesktop: 72px;
    --transitionStyle: ease-in 0.2s;
}

* { box-sizing: border-box; }

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

body {
    margin: 0;
    font-family: var(--fontFamily);
    font-size: 15px;
    line-height: 1.6;
    color: var(--colorGrey700);
    background-color: var(--colorGrey50);
}

/* Form controls do not inherit the page font on their own, and several inputs here sit outside
   .field (the search bar, the admin category rows), so set it once for all of them. */
input, select, textarea, button {
    font-family: inherit;
}

h1, h2, h3, h4 {
    color: var(--colorGrey900);
    line-height: 1.25;
    margin: 0 0 16px;
    font-weight: var(--fontWeightBold);
}

h1 { font-size: 34px; letter-spacing: -0.5px; }
h2 { font-size: 26px; letter-spacing: -0.3px; }
h3 { font-size: 19px; }
h4 { font-size: 16px; }

p { margin: 0 0 16px; }

a { color: var(--marketplaceColor); text-decoration: none; }
a:hover { color: var(--marketplaceColorLight); text-decoration: underline; }

img { max-width: 100%; display: block; }

hr { border: 0; border-top: 1px solid var(--colorBorderSubtle); margin: 32px 0; }

/* ---------------------------------------------------------------- layout */

.wrap {
    max-width: var(--contentMaxWidth);
    margin: 0 auto;
    padding: 0 24px;
}

.wrap-wide { max-width: var(--contentMaxWidthPages); margin: 0 auto; padding: 0 24px; }

/* Vertical only. These classes are routinely combined with .wrap / .wrap-wide on the same element
   (`class="wrap-wide section-tight"`), and the `padding` shorthand used to reset the 24px side
   padding to zero — which put every such page flush against the screen edge on narrow viewports. */
.section { padding-top: 56px; padding-bottom: 56px; }
.section-tight { padding-top: 32px; padding-bottom: 32px; }

.section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 24px;
}
.section-head h2 { margin: 0; }

.muted { color: var(--colorGrey500); }
.small { font-size: 13px; }
.center { text-align: center; }
.stack > * + * { margin-top: 16px; }
.row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.row-between { display: flex; gap: 16px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.grow { flex: 1 1 auto; }

/* ---------------------------------------------------------------- topbar */

.topbar {
    background: var(--colorWhite);
    border-bottom: 1px solid var(--colorBorderSubtle);
    position: sticky;
    top: 0;
    z-index: 10;
}

.topbar-inner {
    max-width: var(--contentMaxWidthPages);
    margin: 0 auto;
    padding: 0 24px;
    height: var(--topbarHeightDesktop);
    display: flex;
    align-items: center;
    gap: 24px;
}

.logo {
    font-size: 20px;
    font-weight: var(--fontWeightBold);
    color: var(--colorGrey900);
    letter-spacing: -0.4px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.logo:hover { text-decoration: none; color: var(--marketplaceColor); }
.logo { flex: 0 0 auto; }
/* The full lockup — yarn ball and wordmark — on transparency, so it sits on the white bar without
   a badge behind it. Height-driven: the width follows the artwork's own proportions. */
.logo-mark {
    height: 34px;
    width: auto;
    /* The global img rule caps width at 100% of the parent, and the parent here is a flex item
       sized by its own content — each waits for the other and both settle at zero. Opting out lets
       the width come from the height and the artwork's aspect ratio, as intended. */
    max-width: none;
    display: block;
    flex: 0 0 auto;
}

/* Present for assistive technology, absent on screen. */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.topnav { display: flex; align-items: center; gap: 22px; margin-left: auto; }

.topnav a {
    color: var(--colorGrey700);
    font-weight: var(--fontWeightMedium);
    font-size: 14px;
    white-space: nowrap;
}
.topnav a:hover { color: var(--colorGrey900); text-decoration: none; }
.topnav a.active { color: var(--marketplaceColor); }

/* --- hamburger -----------------------------------------------------------
   Hidden on wide screens, where .topnav is a plain row. The mobile rules live in the
   max-width: 760px block near the bottom of this file. */

/* Visually hidden but still focusable and operable by keyboard. */
.nav-toggle {
    position: absolute;
    width: 1px; height: 1px;
    margin: 0;
    opacity: 0;
}

.nav-burger { display: none; }

.nav-burger span {
    display: block;
    width: 22px; height: 2px;
    border-radius: 2px;
    background: var(--colorGrey800);
    transition: var(--transitionStyle);
}

/* Keyboard focus has to show on the label, since the checkbox itself is invisible. */
.nav-toggle:focus-visible + .nav-burger {
    outline: 2px solid var(--brandBrown);
    outline-offset: 2px;
}

/* Three bars become an X while the menu is open. */
.nav-toggle:checked + .nav-burger span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle:checked + .nav-burger span:nth-child(2) { opacity: 0; }
.nav-toggle:checked + .nav-burger span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ---------------------------------------------------------------- buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 44px;
    padding: 0 22px;
    border: 0;
    border-radius: var(--borderRadiusButton);
    font-family: inherit;
    font-size: 15px;
    font-weight: var(--fontWeightSemiBold);
    cursor: pointer;
    transition: var(--transitionStyle);
    text-decoration: none;
}
.btn:hover { text-decoration: none; }

.btn-primary { background: var(--colorPrimaryButton); color: var(--colorWhite); }
.btn-primary:hover { background: var(--colorPrimaryButtonDark); color: var(--colorWhite); box-shadow: var(--boxShadowButton); }

.btn-secondary {
    background: var(--colorWhite);
    color: var(--colorGrey700);
    border: 1px solid var(--colorBorder);
}
.btn-secondary:hover { border-color: var(--colorGrey700); color: var(--colorGrey900); }

.btn-marketplace { background: var(--marketplaceColor); color: var(--colorWhite); }
.btn-marketplace:hover { background: var(--marketplaceColorLight); color: var(--colorWhite); }

.btn-danger { background: var(--colorWhite); color: var(--colorFail); border: 1px solid var(--colorBorder); }
.btn-danger:hover { border-color: var(--colorFail); }

.btn-sm { height: 34px; padding: 0 14px; font-size: 13px; }
.btn-block { width: 100%; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

.linkbtn {
    background: none; border: 0; padding: 0; cursor: pointer;
    font: inherit; color: var(--marketplaceColor);
}
.linkbtn:hover { text-decoration: underline; }

/* ---------------------------------------------------------------- hero */

.hero {
    position: relative;
    /* Photo behind a brown scrim so the white heading stays legible. The gradient layers under the
       image double as the fallback if the photo ever fails to load. */
    background:
        linear-gradient(rgba(40, 22, 12, .55), rgba(40, 22, 12, .55)),
        url('../img/hero.jpg') center 38% / cover no-repeat,
        radial-gradient(circle at 20% 30%, #c57a50, transparent 55%),
        linear-gradient(135deg, #8a4728, #462514);
    color: var(--colorWhite);
    padding: 96px 0 104px;
    text-align: center;
}
.hero h1 { color: var(--colorWhite); font-size: 40px; max-width: 780px; margin: 0 auto 16px; }
.hero p { color: #f2f2f2; max-width: 620px; margin: 0 auto 32px; font-size: 17px; }

.searchbar {
    display: flex;
    max-width: 620px;
    margin: 0 auto;
    background: var(--colorWhite);
    border-radius: var(--borderRadiusMedium);
    box-shadow: var(--boxShadowPopup);
    overflow: hidden;
}
.searchbar input {
    flex: 1;
    border: 0;
    padding: 0 18px;
    height: 52px;
    font-size: 15px;
    font-family: inherit;
    color: var(--colorGrey900);
}
.searchbar input:focus { outline: none; }
.searchbar button { height: 52px; border-radius: 0; padding: 0 28px; }

.hero-note {
    margin: 36px auto 0;
    max-width: 620px;
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .25);
    border-radius: var(--borderRadiusMedium);
    padding: 14px 18px;
    font-size: 14px;
}
.hero-note strong { display: block; color: var(--colorWhite); }

/* ---------------------------------------------------------------- cards */

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 28px 20px;
}

.card {
    display: block;
    color: inherit;
}
.card:hover { text-decoration: none; }
.card:hover .card-title { color: var(--marketplaceColor); }

.card-media {
    position: relative;
    /* Square rather than 4:3. Knitwear is photographed upright as often as not, and a landscape
       frame cut the top and bottom off those. */
    aspect-ratio: 1 / 1;
    border-radius: var(--borderRadiusImage);
    overflow: hidden;
    background: var(--colorGrey100);
    margin-bottom: 10px;
    transition: var(--transitionStyle);
}
.card:hover .card-media { box-shadow: var(--boxShadowListingCard); }
.card-media img { width: 100%; height: 100%; object-fit: cover; }

/* Placeholder tile used until a seller uploads a photo. */
.placeholder {
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
    font-size: 26px; font-weight: var(--fontWeightBold);
    color: rgba(255, 255, 255, .9);
    letter-spacing: 1px;
}

.card-price { font-weight: var(--fontWeightBold); color: var(--colorGrey900); }
.card-title { font-weight: var(--fontWeightMedium); color: var(--colorGrey900); }
.card-seller { font-size: 13px; color: var(--colorGrey500); }

.badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: var(--fontWeightSemiBold);
    text-transform: uppercase;
    letter-spacing: .4px;
    background: var(--colorGrey100);
    color: var(--colorGrey600);
}
.badge-ok { background: var(--colorSuccessSubtle); color: var(--colorSuccess); }
.badge-warn { background: var(--colorAttentionSubtle); color: var(--colorAttentionDark); }
.badge-off { background: var(--colorFailSubtle); color: var(--colorFail); }
.badge-mp { background: var(--brandCream); color: var(--marketplaceColor); }

.card-media .badge { position: absolute; top: 10px; left: 10px; background: var(--colorWhite); }

/* ---------------------------------------------------------------- panels */

.panel {
    background: var(--colorWhite);
    border: 1px solid var(--colorBorderSubtle);
    border-radius: var(--borderRadiusMedium);
    padding: 24px;
}
.panel + .panel { margin-top: 20px; }
/* ...but only where they really are stacked, which is plain block flow. In a grid the gap
   already does the spacing, and the sibling margin pushed every panel except the first 20px
   down - so the traader cards came out ragged, one tall and the rest hanging below its top
   edge, and the two "Hvorfor bruke Traad?" panels sat at different heights. */
.grid > .panel + .panel,
.split > .panel + .panel { margin-top: 0; }

/* A display name is often two words and wraps, which made one traader card taller than the rest.
   The grid already stretches the boxes to match; pinning the grey line to the bottom lines up
   what is inside them too. */
.trader-card { display: flex; flex-direction: column; align-items: center; }
.trader-meta { margin-top: auto; }
.panel-tight { padding: 16px 20px; }

/* Banner on an editorial page. Sits between the heading and the lead, and the fixed ratio keeps
   the page from jumping as it loads. */
.page-banner {
    display: block;
    width: 100%;
    aspect-ratio: 5 / 2;
    object-fit: cover;
    border-radius: var(--borderRadiusImage);
    margin: 0 0 20px;
}

/* The uncropped one. No fixed ratio and no object-fit, so the picture keeps the proportions it was
   uploaded with; max-width only stops an oversized file from pushing the page sideways, and because
   height follows automatically nothing is ever cut off. A small image stays small. */
.page-image {
    display: block;
    max-width: 100%;
    height: auto;
    border-radius: var(--borderRadiusImage);
    margin: 0 0 20px;
}

/* Portrait of a traader. Unlike .avatar this is a rectangle you can actually see a face in; the
   fixed 3:4 ratio matches the rendition MediaUrls asks for, so nothing reflows as it loads. */
.portrait {
    flex: 0 0 auto;
    width: 220px;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: var(--borderRadiusImage);
    display: block;
}
.portrait-sm { width: 132px; }

/* "Prøv denne" on a product page. Deliberately the loudest button on the page - it is the one
   thing here nobody expects to be able to do. */
.tryon { margin-top: 10px; }
.btn-tryon {
    /* Twice the height of an ordinary button, and the only outlined one on the page. .btn fixes a
       44px height, so that has to be overridden rather than padded around - and as a minimum rather
       than a fixed height, because the second line is sometimes a whole sentence. */
    height: auto;
    min-height: 88px;
    flex-direction: column;
    gap: 2px;
    padding: 12px 18px;
    background: var(--colorWhite);
    color: var(--brandBrown);
    border: 3px solid var(--brandBrown);
    font-size: 15px;
    font-weight: var(--fontWeightSemiBold);
    line-height: 1.3;
    text-align: center;
    animation: tryon-pulse 2.4s ease-in-out infinite;
}
.btn-tryon:hover {
    background: var(--brandBrown);
    color: var(--colorWhite);
    text-decoration: none;
    animation: none;          /* it has your attention now; stop waving */
}
.btn-tryon:disabled {
    background: var(--colorWhite);
    color: var(--colorGrey500);
    border-color: var(--colorGrey300);
    cursor: not-allowed;
    animation: none;
}

/* A ring that swells out of the border and fades. Colour written out rather than taken from the
   token, because a box-shadow needs the alpha and CSS cannot add one to a hex variable. */
@keyframes tryon-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(168, 91, 53, .40); }
    70%  { box-shadow: 0 0 0 12px rgba(168, 91, 53, 0); }
    100% { box-shadow: 0 0 0 0 rgba(168, 91, 53, 0); }
}

/* Anyone who has asked their system to stop moving things gets the button without the pulse. It
   still reads as the loudest thing here: it is the only outlined button on the page. */
@media (prefers-reduced-motion: reduce) {
    .btn-tryon { animation: none; }
}

/* The allowance, on its own line under the label and deliberately quieter than it. */
.tryon-count {
    display: block;
    font-size: 12px;
    font-weight: 400;
    opacity: .85;
}
.tryon-note { margin: 8px 0 0; }

/* The two tiles that show what is about to happen: your own face, and a blank for the picture that
   does not exist yet. Equal halves, so neither reads as the more important of the two. */
.tryon-preview {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-top: 12px;
}
.tryon-tile {
    width: 100%;
    aspect-ratio: 3 / 4;
    border-radius: var(--borderRadiusImage);
    object-fit: cover;
    display: block;
}
/* An author rule with display:grid or display:flex beats the browser's own [hidden] { display:none },
   so both blocks need to be told again - otherwise they are on screen whatever the markup says. */
.tryon-preview[hidden],
.tryon-loading[hidden] { display: none; }

.tryon-tile-blank {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--colorGrey50);
    border: 2px dashed var(--colorGrey200);
    color: var(--colorGrey300);
    font-size: 40px;
    font-weight: var(--fontWeightBold);
    line-height: 1;
}

/* The wait. Half a minute of nothing looks like a broken page, so there is something turning and a
   plain warning not to reload. */
.tryon-loading {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-top: 12px;
    padding: 14px 16px;
    border: 1px solid var(--colorBorderSubtle);
    border-radius: var(--borderRadiusMedium);
    background: var(--colorGrey50);
    color: var(--colorGrey700);
}
.tryon-loading strong { display: block; font-size: 14px; color: var(--colorGrey900); }
/* The seconds counter, quieter than the heading it sits in - it is reassurance, not information. */
.tryon-loading strong span { font-weight: 400; color: var(--colorGrey500); }
.tryon-loading p { margin: 2px 0 0; font-size: 13px; line-height: 1.45; }

.tryon-loading .yarn {
    flex: 0 0 auto;
    color: var(--brandBrown);
    animation: yarn-spin 2.8s linear infinite;
}

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

/* Still a yarn ball, just not a turning one. The text carries the message on its own. */
@media (prefers-reduced-motion: reduce) {
    .tryon-loading .yarn { animation: none; }
}
.tryon-image {
    display: block;
    width: 100%;
    margin: 12px 0 10px;
    border-radius: var(--borderRadiusImage);
}

/* The profile header holds the round avatar, the text and - when there is one - the portrait.
   Aligned to the top rather than centred, because a 4:3 picture next to two lines of text looks
   wrong when the two are centred on each other. The text may shrink so the portrait keeps its
   place on the same line; below 700px everything stacks. */
.profile-head { align-items: flex-start; }
/* flex-basis rather than width: .grow defaults to a basis of its own content, and a long bio is
   wide enough that the row wrapped and left the portrait stranded on a line of its own. A fixed
   basis with min-width:0 lets the text shrink instead, so the portrait keeps its place beside it. */
.profile-head > .grow { flex: 1 1 260px; min-width: 0; }
.portrait-empty {
    display: flex; align-items: center; justify-content: center;
    text-align: center;
    background: var(--colorGrey100);
    color: var(--colorGrey500);
    font-size: 13px;
}

@media (max-width: 700px) {
    .portrait { width: 100%; max-width: 220px; }
}

.avatar {
    width: 56px; height: 56px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: var(--colorWhite);
    font-weight: var(--fontWeightBold);
    flex: 0 0 auto;
}
.avatar-lg { width: 88px; height: 88px; font-size: 28px; }
.avatar-sm { width: 32px; height: 32px; font-size: 12px; }

/* When the slot holds a real photo the avatar is an <img>, not a letter tile. */
img.avatar { display: block; object-fit: cover; }

/* ---------------------------------------------------------------- forms */

.field { margin-bottom: 18px; }
.field label { display: block; font-size: 13px; font-weight: var(--fontWeightSemiBold); color: var(--colorGrey800); margin-bottom: 6px; }

.field input[type=text], .field input[type=email], .field input[type=password],
.field input[type=number], .field input[type=search], .field select, .field textarea {
    width: 100%;
    padding: 11px 14px;
    font: inherit;
    color: var(--colorGrey900);
    background: var(--colorWhite);
    border: 1px solid var(--colorBorder);
    border-radius: var(--borderRadiusMedium);
    transition: var(--transitionStyle);
}
.field textarea { min-height: 140px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
    outline: none;
    border-color: var(--marketplaceColor);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brandBrown) 22%, transparent);
}
.field .hint { font-size: 12px; color: var(--colorGrey500); margin-top: 5px; }

.check { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 12px; }
.check input { margin-top: 3px; accent-color: var(--brandBrown); cursor: pointer; }
/* The text is the target most people aim for, so give it the same cursor as the box. The box
   itself stays small; the label is what makes the row comfortable to hit. */
.check label { margin: 0; font-weight: 400; font-size: 14px; color: var(--colorGrey700); cursor: pointer; }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }

.validation { color: var(--colorFail); font-size: 13px; margin-top: 5px; display: block; }
.validation-summary { background: var(--colorFailSubtle); border: 1px solid #f5c2c2; color: #a00; padding: 12px 16px; border-radius: var(--borderRadiusMedium); margin-bottom: 20px; }
.validation-summary ul { margin: 0; padding-left: 18px; }

/* asp-validation-summary="All" emits the summary container even when there is nothing wrong, so
   without this the styled box shows up as an empty red bar. Same for the per-field spans. */
.validation-summary-valid { display: none; }
.field-validation-valid { display: none; }

.alert { padding: 12px 16px; border-radius: var(--borderRadiusMedium); margin-bottom: 24px; font-size: 14px; }
/* The banner in _Layout that carries TempData["Message"]. It used to be green, which clashed with
   the brown palette — and misread the content, because this one channel also carries "Kjøpet ble
   avbrutt." and "Kunne ikke sende meldingen." It is a notice, not a success badge, so it wears the
   brand colours. The solid left edge is what separates it from the quieter .alert-info: this one
   reports something that just happened, rather than standing explanation. */
.alert-ok { background: var(--brandCream); border: 1px solid var(--colorBorder); border-left: 4px solid var(--brandBrown); color: var(--brandBrownDark); }
.alert-info { background: var(--brandCream); border: 1px solid var(--colorBorder); color: var(--brandBrownDark); }

.form-narrow { max-width: 440px; margin: 0 auto; }

/* ---------------------------------------------------------------- browse */

.browse { display: grid; grid-template-columns: 232px 1fr; gap: 40px; align-items: start; }

.filters { position: sticky; top: 96px; }
.filter-group + .filter-group { margin-top: 26px; }
.filter-group h4 { margin: 0 0 10px; font-size: 13px; text-transform: uppercase; letter-spacing: .5px; color: var(--colorGrey500); }
.filter-group ul { list-style: none; margin: 0; padding: 0; }
.filter-group li { margin-bottom: 6px; }
.filter-group a { color: var(--colorGrey700); font-size: 14px; display: flex; justify-content: space-between; gap: 8px; }
.filter-group a:hover { color: var(--colorGrey900); text-decoration: none; }
.filter-group a.on { color: var(--marketplaceColor); font-weight: var(--fontWeightSemiBold); }
.filter-count { color: var(--colorGrey400); font-size: 12px; }

/* --- collapsible facet groups (<details>/<summary>) --- */

/* Same look as the .filter-group h4 headings it sits alongside, plus a chevron. */
.filter-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
    padding: 2px 0;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--colorGrey500);
    cursor: pointer;
    list-style: none;               /* drop the default disclosure triangle */
    user-select: none;
}
.filter-toggle::-webkit-details-marker { display: none; }   /* Safari */
.filter-toggle:hover { color: var(--colorGrey800); }

.filter-toggle:focus-visible {
    outline: 2px solid var(--brandBrown);
    outline-offset: 2px;
    border-radius: var(--borderRadius);
}

/* Chevron, pushed to the right edge. Points down when collapsed, up when open. */
.filter-toggle::after {
    content: "";
    width: 6px; height: 6px;
    margin-left: auto;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform var(--transitionStyle);
}
details[open] > .filter-toggle::after { transform: translateY(1px) rotate(-135deg); }

.toolbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
    padding-bottom: 18px; margin-bottom: 24px;
    border-bottom: 1px solid var(--colorBorderSubtle);
}
.toolbar select { padding: 8px 12px; border: 1px solid var(--colorBorder); border-radius: var(--borderRadiusMedium); font: inherit; background: var(--colorWhite); }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
.chip {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--colorWhite); border: 1px solid var(--colorBorder);
    border-radius: 999px; padding: 4px 12px; font-size: 13px; color: var(--colorGrey700);
}
.chip:hover { border-color: var(--colorGrey700); text-decoration: none; color: var(--colorGrey900); }

.pager { display: flex; gap: 6px; justify-content: center; margin-top: 40px; flex-wrap: wrap; }
.pager a, .pager span {
    min-width: 38px; height: 38px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--colorBorder); border-radius: var(--borderRadiusMedium);
    background: var(--colorWhite); color: var(--colorGrey700); font-size: 14px; padding: 0 10px;
}
.pager a:hover { border-color: var(--colorGrey700); text-decoration: none; }
.pager .on { background: var(--colorGrey900); border-color: var(--colorGrey900); color: var(--colorWhite); }

.empty { text-align: center; padding: 72px 24px; color: var(--colorGrey500); }

/* ---------------------------------------------------------------- listing page */

.listing { display: grid; grid-template-columns: 1fr 360px; gap: 48px; align-items: start; }

.gallery-main {
    position: relative;        /* the arrows hang off this */
    aspect-ratio: 4 / 3;
    border-radius: var(--borderRadiusImage);
    overflow: hidden;
    /* White rather than grey: the rendition is padded white to fill the box, so anything showing
       around it has to be the same colour or the padding becomes visible as a seam. */
    background: var(--colorWhite);
    margin-bottom: 12px;
}
/* contain, to match the Fit rendition. The two are the same shape today, so cover would not crop
   either - but this way a change to one cannot quietly start cutting the picture. */
.gallery-main img { width: 100%; height: 100%; object-fit: contain; }
/* Brown disc, white chevron, sitting over the picture. Only rendered when there is more than one
   photo, so there is never an arrow that does nothing. */
.gallery-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--brandBrown);
    color: var(--colorWhite);
    cursor: pointer;
    opacity: .85;
    transition: var(--transitionStyle);
}
.gallery-nav:hover { background: var(--brandBrownDark); opacity: 1; }
.gallery-nav:focus-visible { outline: 2px solid var(--brandBrownDark); outline-offset: 3px; opacity: 1; }
.gallery-prev { left: 12px; }
.gallery-next { right: 12px; }

/* Which photo is on show, so the thumbs are not just decoration once the arrows are in use. */
.gallery-thumbs .thumb.is-current { outline: 2px solid var(--brandBrown); outline-offset: 2px; }

.gallery-thumbs { display: flex; gap: 10px; flex-wrap: wrap; }
.gallery-thumbs .thumb { width: 78px; height: 78px; border-radius: var(--borderRadiusImageSmall); overflow: hidden; background: var(--colorGrey100); }
.gallery-thumbs img { width: 100%; height: 100%; object-fit: cover; }

.buybox { position: sticky; top: 96px; }
.buybox .price { font-size: 30px; font-weight: var(--fontWeightBold); color: var(--colorGrey900); line-height: 1.2; }

.spec { display: grid; grid-template-columns: 130px 1fr; gap: 8px 16px; font-size: 14px; }
.spec dt { color: var(--colorGrey500); }
.spec dd { margin: 0; color: var(--colorGrey900); }

.review { padding: 16px 0; border-top: 1px solid var(--colorBorderSubtle); }
.stars { color: var(--colorAttention); letter-spacing: 2px; }

/* ---------------------------------------------------------------- tables */

.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th {
    text-align: left; font-size: 12px; text-transform: uppercase; letter-spacing: .5px;
    color: var(--colorGrey500); font-weight: var(--fontWeightSemiBold);
    padding: 0 12px 10px; border-bottom: 1px solid var(--colorBorderSubtle);
}
.table td { padding: 14px 12px; border-bottom: 1px solid var(--colorBorderSubtle); vertical-align: middle; }
.table tr:last-child td { border-bottom: 0; }
.table .num { text-align: right; white-space: nowrap; }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin-bottom: 28px; }
.stat { background: var(--colorWhite); border: 1px solid var(--colorBorderSubtle); border-radius: var(--borderRadiusMedium); padding: 18px 20px; }
.stat .n { font-size: 26px; font-weight: var(--fontWeightBold); color: var(--colorGrey900); line-height: 1.2; }
.stat .l { font-size: 13px; color: var(--colorGrey500); }

/* ---------------------------------------------------------------- how it works */

.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 32px; }
.step-n {
    width: 36px; height: 36px; border-radius: 50%;
    background: var(--brandCream); color: var(--marketplaceColor);
    display: flex; align-items: center; justify-content: center;
    font-weight: var(--fontWeightBold); margin-bottom: 14px;
}

.split { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }

/* ---------------------------------------------------------------- footer */

.footer {
    background: var(--colorGrey900);
    color: var(--colorGrey300);
    padding: 48px 0 32px;
    margin-top: 72px;
    font-size: 14px;
}
.footer a { color: var(--colorGrey200); }
.footer a:hover { color: var(--colorWhite); }
.footer h4 { color: var(--colorWhite); font-size: 13px; text-transform: uppercase; letter-spacing: .5px; margin-bottom: 12px; }
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li { margin-bottom: 8px; }
.footer-cols { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 32px; }
.footer-base { border-top: 1px solid #2c2c30; margin-top: 32px; padding-top: 20px; color: var(--colorGrey500); font-size: 13px; }

/* ---------------------------------------------------------------- responsive */

@media (max-width: 900px) {
    .browse { grid-template-columns: 1fr; }
    .filters { position: static; }
    .listing { grid-template-columns: 1fr; gap: 32px; }
    .buybox { position: static; }
    .footer-cols { grid-template-columns: 1fr 1fr; }
    .split { grid-template-columns: 1fr; }
}

/* The full nav needs roughly 700px once someone is signed in, so it collapses well before that. */
@media (max-width: 760px) {
    .nav-burger {
        display: flex;
        flex-direction: column;
        justify-content: center;
        gap: 5px;
        margin-left: auto;
        width: 44px; height: 44px;
        align-items: center;
        cursor: pointer;
        border-radius: var(--borderRadiusButton);
        flex: 0 0 auto;
    }
    .nav-burger:hover { background: var(--colorGrey50); }

    /* Drops out of the flex row and hangs below the whole bar, full width. */
    .topnav {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        margin: 0;
        padding: 8px 24px 16px;
        background: var(--colorWhite);
        border-bottom: 1px solid var(--colorBorderSubtle);
        box-shadow: var(--boxShadow);
    }
    .nav-toggle:checked ~ .topnav { display: flex; }

    /* Full-width rows, comfortable tap targets. */
    .topnav a {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 13px 2px;
        font-size: 16px;
        border-bottom: 1px solid var(--colorBorderSubtle);
    }
    .topnav a:last-child { border-bottom: 0; }
    .topnav a.btn { justify-content: center; margin-top: 12px; border-bottom: 0; font-size: 15px; }

    .topnav form { display: block !important; padding: 13px 2px 0; }
    .topnav .linkbtn { font-size: 16px; }
}

@media (max-width: 640px) {
    .topbar-inner { height: var(--topbarHeight); gap: 12px; }
    .hero { padding: 64px 0 72px; }
    .hero h1 { font-size: 28px; }
    .grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 20px 14px; }
    .field-row { grid-template-columns: 1fr; }
    .footer-cols { grid-template-columns: 1fr; }
    h1 { font-size: 26px; }
    h2 { font-size: 21px; }
}

/* Seller-authored prose is stored as plain text; keep the author's line breaks. */
.prose { white-space: pre-wrap; }

/* ---------------------------------------------------------------- messages */

.inbox-row {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--colorBorderSubtle);
    color: inherit;
}
.inbox-row:last-child { border-bottom: 0; }
.inbox-row:hover { background: var(--colorGrey50); text-decoration: none; }
.inbox-row.unread { background: var(--brandCream); }
.inbox-row.unread:hover { background: #f5ddc9; }

.inbox-main { flex: 1 1 auto; min-width: 0; }
.inbox-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.inbox-name { font-weight: var(--fontWeightSemiBold); color: var(--colorGrey900); }
.inbox-sub { font-size: 13px; color: var(--colorGrey600); }
.inbox-snippet {
    font-size: 13px; color: var(--colorGrey500);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.inbox-meta { text-align: right; font-size: 13px; color: var(--colorGrey500); white-space: nowrap; flex: 0 0 auto; }

.dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--brandBrown); display: inline-block; flex: 0 0 auto;
}

/* Unread count on the Meldinger menu item. */
.navcount {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 18px; padding: 0 5px; margin-left: 4px;
    border-radius: 999px; background: var(--brandBrown); color: var(--colorWhite);
    font-size: 11px; font-weight: var(--fontWeightBold); line-height: 1;
}

.msg { margin-bottom: 18px; display: flex; flex-direction: column; align-items: flex-start; }
.msg.mine { align-items: flex-end; }
.msg-bubble {
    max-width: min(80%, 560px);
    padding: 12px 16px;
    border-radius: 14px 14px 14px 4px;
    background: var(--colorGrey50);
    border: 1px solid var(--colorBorderSubtle);
    color: var(--colorGrey800);
}
.msg.mine .msg-bubble {
    border-radius: 14px 14px 4px 14px;
    background: var(--brandCream);
    border-color: var(--colorBorder);
}
.msg-bubble .prose { margin: 0; }
.msg-meta { font-size: 12px; color: var(--colorGrey500); margin-top: 5px; }

/* --- price range slider -------------------------------------------------
   Two <input type=range> stacked on one track. The inputs themselves ignore pointer events so
   clicks fall through to whichever thumb is under the cursor; only the thumbs are interactive. */

.pricerange { position: relative; height: 30px; margin: 4px 0 2px; }

.pricerange-track {
    position: absolute; top: 13px; left: 0; right: 0; height: 4px;
    border-radius: 999px;
    background: var(--colorBorder);
}

/* The selected span, driven by the --min-pct / --max-pct custom properties. */
.pricerange-track::after {
    content: "";
    position: absolute; top: 0; bottom: 0;
    left: var(--min-pct, 0%);
    right: calc(100% - var(--max-pct, 100%));
    background: var(--brandBrown);
    border-radius: 999px;
}

.pricerange input[type=range] {
    position: absolute; top: 0; left: 0;
    width: 100%; height: 30px;
    margin: 0;
    background: none;
    -webkit-appearance: none;
    appearance: none;
    pointer-events: none;
}
.pricerange input[type=range]::-webkit-slider-runnable-track { background: none; border: none; }
.pricerange input[type=range]::-moz-range-track { background: none; border: none; }

.pricerange input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    pointer-events: auto;
    width: 18px; height: 18px;
    margin-top: 0;
    border-radius: 50%;
    background: var(--colorWhite);
    border: 2px solid var(--brandBrown);
    box-shadow: var(--boxShadowLight);
    cursor: grab;
}
.pricerange input[type=range]::-moz-range-thumb {
    pointer-events: auto;
    width: 18px; height: 18px;
    border-radius: 50%;
    background: var(--colorWhite);
    border: 2px solid var(--brandBrown);
    box-shadow: var(--boxShadowLight);
    cursor: grab;
}
.pricerange input[type=range]:active::-webkit-slider-thumb { cursor: grabbing; }
.pricerange input[type=range]:active::-moz-range-thumb { cursor: grabbing; }

.pricerange input[type=range]:focus { outline: none; }
.pricerange input[type=range]:focus-visible::-webkit-slider-thumb {
    outline: 2px solid var(--brandBrown);
    outline-offset: 2px;
}
.pricerange input[type=range]:focus-visible::-moz-range-thumb {
    outline: 2px solid var(--brandBrown);
    outline-offset: 2px;
}

.pricerange-values {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: 13px;
    color: var(--colorGrey700);
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- background thread

   The decorative thread behind every page (markup in _Layout.cshtml). Fixed to the viewport so it
   covers the full width and height whatever the page length, and z-index -1 so it sits above the
   page's background colour but under every panel, card and bar — which is what makes it read as a
   thread running *behind* the content rather than over it. */

.threadbg {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    pointer-events: none;
}

/* Kept only a few percent off the page background — at these opacities the thread is texture you
   notice after the content, not a line that competes with it. The widths stay where they are on
   purpose: thinning the strokes as well would drop them below a pixel of coverage and leave them
   aliasing in and out along the curve instead of fading evenly. */

.threadbg-main {
    stroke: var(--brandBrownSoft);
    stroke-width: 2;
    opacity: .10;
}

.threadbg-soft {
    stroke: var(--brandBrownSoft);
    stroke-width: 1.5;
    opacity: .055;
}

.threadbg-stitch {
    stroke: var(--brandBrownSoft);
    stroke-width: 1.5;
    stroke-dasharray: 9 13;
    opacity: .07;
}

/* On a phone the thread is squeezed into a tall, narrow box, so the curves bunch up behind the
   text. Fading it further keeps it from reading as smudges. */
@media (max-width: 760px) {
    .threadbg-main { opacity: .07; }
    .threadbg-soft, .threadbg-stitch { opacity: .04; }
}

/* ---------------------------------------------------------------- colour picker + file queue */

/* One checkbox per base colour on the edit form. auto-fill rather than a fixed column count so it
   collapses to two columns on a phone without a second media query. */
.colourpick {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 6px 14px;
}

.colourpick-item { display: flex; align-items: center; gap: 8px; }
.colourpick-item input { width: 16px; height: 16px; accent-color: var(--brandBrown); margin: 0; cursor: pointer; }
.colourpick-item label { font-size: 14px; font-weight: 400; color: var(--colorGrey800); cursor: pointer; }

/* The images queued for upload, listed so it is obvious that a second pick added to the first
   rather than replacing it. */
.filequeue { list-style: none; margin: 10px 0 0; padding: 0; }
.filequeue:empty { display: none; }

.filequeue li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 12px;
    margin-bottom: 6px;
    background: var(--brandCream);
    border: 1px solid var(--colorBorder);
    border-radius: var(--borderRadiusMedium);
    font-size: 14px;
    color: var(--brandBrownDark);
}

.filequeue li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.filequeue li button { color: var(--brandBrown); text-decoration: underline; flex: none; }

/* The "Skjul reserverte" / "Skjul solgte" boxes under the price slider. */
.filter-checks { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.check-inline { display: flex; align-items: center; gap: 8px; }
.check-inline input { width: 15px; height: 15px; accent-color: var(--brandBrown); margin: 0; flex: none; cursor: pointer; }
.check-inline label { font-size: 13px; color: var(--colorGrey700); cursor: pointer; }

/* ---------------------------------------------------------------- file picker

   A file input has no styling of its own — it renders as a small grey "Choose File" control that
   disappears on a long form. The input is lifted out of the layout (but kept focusable, so it is
   still reachable by keyboard) and the label is what you see and click. */

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

.field .filepick {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 26px 20px;
    text-align: center;
    background: var(--colorWhite);
    border: 2px dashed var(--colorBorder);
    border-radius: var(--borderRadiusMedium);
    cursor: pointer;
    transition: var(--transitionStyle);
}

.field .filepick strong { color: var(--brandBrownDark); font-size: 15px; }
.field .filepick span { color: var(--colorGrey600); font-size: 13px; }

.field .filepick:hover,
.field .filepick.is-over {
    background: var(--brandCream);
    border-color: var(--brandBrown);
}

/* The real focus ring, since the control it belongs to is not the thing on screen. */
.filepick-input:focus-visible + .field .filepick,
.filepick-input:focus-visible + .filepick {
    outline: 2px solid var(--brandBrown);
    outline-offset: 2px;
}

/* The "add another image" tile that closes the gallery grid — where you actually look when you
   want one more picture. Sized like a photo cell so the row reads as a strip with an empty slot. */
.addtile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    aspect-ratio: 1/1;
    background: var(--colorWhite);
    border: 2px dashed var(--colorBorder);
    border-radius: var(--borderRadiusMedium);
    color: var(--brandBrownDark);
    font-size: 14px;
    text-align: center;
    cursor: pointer;
    transition: var(--transitionStyle);
}

.addtile:hover,
.addtile.is-over {
    background: var(--brandCream);
    border-color: var(--brandBrown);
}

.addtile-plus { font-size: 30px; line-height: 1; color: var(--brandBrown); }

/* While an auto-save is in flight. A large photo takes a moment to post, and without this the page
   just sits there looking as though the click did nothing. */
.filepick-busy { display: none; }

.field .filepick.is-busy,
.addtile.is-busy {
    pointer-events: none;
    opacity: .6;
    border-style: solid;
    border-color: var(--brandBrown);
}

.field .filepick.is-busy .filepick-idle { display: none; }
.field .filepick.is-busy .filepick-busy { display: inline; }

/* Product row on Min side: cover picture in front of the title. */
.rowitem { display: flex; align-items: center; gap: 12px; color: var(--colorGrey900); font-weight: var(--fontWeightMedium); }
.rowitem:hover { text-decoration: none; color: var(--marketplaceColor); }

.rowitem-media {
    flex: 0 0 auto;
    width: 48px; height: 48px;
    border-radius: var(--borderRadiusImageSmall);
    overflow: hidden;
    background: var(--brandCream);
    display: flex; align-items: center; justify-content: center;
}
.rowitem-media img { width: 100%; height: 100%; object-fit: cover; }

.rowitem-empty { font-size: 14px; font-weight: var(--fontWeightBold); color: var(--brandBrown); }
.rowitem-title { min-width: 0; }

/* ---------------------------------------------------------------- Vipps

   Vipps' own orange, not a brand colour of ours — the button has to look like Vipps to be trusted,
   and their guidelines require the mark to keep its colour. */

.btn-vipps {
    background: #ff5b24;
    color: var(--colorWhite);
    border: 1px solid #ff5b24;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}
.btn-vipps:hover { background: #e94f1d; border-color: #e94f1d; color: var(--colorWhite); text-decoration: none; }

.btn-vipps-mark {
    font-weight: var(--fontWeightBold);
    letter-spacing: .2px;
    background: var(--colorWhite);
    color: #ff5b24;
    border-radius: 4px;
    padding: 1px 7px;
    font-size: 13px;
}

/* "eller" rule between the two ways in. */
.orsplit {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 18px 0;
    color: var(--colorGrey500);
    font-size: 13px;
}
.orsplit::before,
.orsplit::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--colorBorderSubtle);
}

/* The primary way into the site, so it carries more weight than an ordinary button. */
.btn-lg {
    padding: 16px 24px;
    font-size: 17px;
    border-radius: var(--borderRadiusButton);
}
.btn-lg .btn-vipps-mark { font-size: 15px; padding: 2px 9px; }

/* The way to a new account, on the login page. Was a line of small grey text under the form, which
   is easy to miss when you are on the wrong page entirely. */
.signup-nudge {
    margin-top: 32px;
    padding-top: 28px;
    border-top: 1px solid var(--colorBorderSubtle);
    text-align: center;
}
.signup-nudge p {
    margin: 0 0 14px;
    font-size: 18px;
    color: var(--colorGrey800);
}

/* The break-glass knock-spot: a summary with no marker and no ink, in the quiet space under the
   sign-up prompt. Invisible, but still reachable by keyboard — an operator locked out of Vipps
   should not also need a mouse. */
.backdoor > summary {
    list-style: none;
    display: block;
    height: 28px;
    cursor: default;
}
.backdoor > summary::-webkit-details-marker { display: none; }
.backdoor > summary:focus-visible { outline: 2px solid var(--brandBrown); outline-offset: 2px; }

/* "Brukt" marks the condition of the item, while Solgt/Reservert mark where it is in its life.
   Different things, so they sit on opposite corners and can both show at once. */
.card-media .badge-used {
    left: auto;
    right: 10px;
    background: var(--brandBrownDark);
    color: var(--colorWhite);
}

/* Min side while the shop is paused — a warm band so the state is obvious on arrival, since
   everything else on the page looks exactly as it always does. */
.panel-paused {
    background: var(--brandCream);
    border-color: var(--brandBrown);
}

/* "Spesialbestill" sits with "Brukt" rather than with the status badge: both say what the item is,
   while Solgt/Reservert say where it is in its life. Stacked so the two can show together. */
/* "Spesialbestill" wears the same pale pill as Solgt and Reservert, in the brand tint rather than
   a status colour — it says something about the product, not about where it is in its life. */
.badge-special { background: var(--brandCream); color: var(--brandBrownDark); }

/* The top-left corner holds the status badge and "Spesialbestill", stacked. They live in a flow
   container instead of being positioned one by one, so a listing that is both keeps both legible. */
.card-badges {
    position: absolute;
    top: 10px;
    left: 10px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
}

/* Inside the stack the badges are laid out by the container, not pinned to the corner themselves. */
.card-media .card-badges .badge { position: static; }

/* Price and delivery time on one baseline, so the time reads as a qualifier on the price rather
   than as a separate fact underneath it. */
.pricerow { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.pricerow .prep { font-size: 14px; color: var(--colorGrey600); }

/* A field that is shown for reference but cannot be changed. Muted rather than merely greyed, so it
   reads as "this is settled" instead of "this is broken". */
.field input:disabled {
    background: var(--colorGrey50);
    color: var(--colorGrey600);
    cursor: not-allowed;
}
