/* ============================================================================
   GUIDO - shared components
   ----------------------------------------------------------------------------
   Alles wat op meer dan één pagina voorkomt: sectielabels, de zoekbalk, de
   categoriechips, de bonkaart en de lege staat. Vereist theme.css.
   Bevat bewust geen enkele hexcode, alle kleuren komen uit een rol-token.

   Laadorde in Site.Master:
       style.css  ->  theme.css  ->  components.css
   daarna per pagina home.css / vouchers.css via HeadContent.
   ============================================================================ */

/* =========================================================== plakkende kop
   De header van Site.Master scrollde weg, terwijl de filterbalk van het
   bonnenoverzicht op --header-h bleef plakken. Daardoor bleef er een strook
   van 65px open waar de bonnen achter langs schoven.

   Deze regel staat hier en niet in style.css omdat components.css er na
   geladen wordt: zo overschrijft hij de bestaande .header zonder dat
   bestand aan te raken.
   ========================================================================= */
.header {
    position: sticky;
    top: 0;
    z-index: var(--z-header);
}

/* De stadskiezer vulde de lege ruimte naast het logo niet op. In style.css
   staat .city-pill-select-wrap op display:inline-block zonder flex-grow, en
   omdat .header al display:flex is wordt dat een flexitem met "flex: 0 1 auto":
   het neemt dus alleen de breedte van zijn inhoud, met 170px als bodem.

   flex: 1 1 auto laat hem de rest opvullen, min-width: 0 laat hem alsnog
   krimpen op een scherm van 320px in plaats van te overlopen.

   Deze regel staat hier en niet in style.css omdat components.css er na
   geladen wordt. De extra .header ervoor maakt hem ook zwaarder dan het
   origineel, dus de volgorde van de bestanden maakt niet meer uit. */
.header .city-pill-select-wrap {
    flex: 1 1 auto;
    min-width: 0;
}

/* het logo hield de tussenruimte met een marge, dat mag de header zelf doen */
.header { gap: 10px; }

/* Het logo krijgt een vaste voet en een bovengrens. Zonder breedte op de img
   komt die uit de intrinsieke maat van GuidoLogo.svg, en juist daar verschillen
   engines: mobiel Safari rekt een <img> met een svg zonder width- en
   height-attribuut op tot de beschikbare ruimte, waar desktop Chrome de
   verhouding uit de viewBox aanhoudt. Op de telefoon slokte het logo zo de
   ruimte op die de stadskiezer moest krijgen. In Chrome met mobiel nagebootst
   zie je dat niet, want dat blijft dezelfde renderer.

   flex: 0 0 auto en een max-width maken de breedte voorspelbaar, los van hoe
   de svg is opgeslagen. */
.header .logo {
    flex: 0 0 auto;
    max-width: 110px;
}

.header .logo img {
    display: block;
    height: 40px;
    width: auto;
    max-width: 100%;
    margin-right: 0;
}

/* een anker mag niet onder de plakkende kop verdwijnen */
html { scroll-padding-top: calc(var(--header-h) + 8px); }

/* ------------------------------------------------------------- sectielabel */
.gg-eyebrow {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--color-structure);
    opacity: .7;
    margin: 0;
}

.gg-section { margin-top: 24px; }

/* Een sectietitel die los boven zijn inhoud staat krijgt dezelfde afstand
   als .gg-section-head hieronder (10px), zodat "Categorieën" en "In de
   buurt" hetzelfde ritme volgen als "Bonnen deze week". De labels op de
   andere pagina's (.ac-label, .cd-label, .vd-label, .uv-label) staan op
   dezelfde 10px. */
.gg-section > .gg-eyebrow { margin-bottom: 10px; }

.gg-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}

.gg-section-link {
    font-size: 12px;
    font-weight: 600;
    color: var(--color-brand);
    text-decoration: none;
    white-space: nowrap;
}

.gg-section-link:hover { text-decoration: underline; }

/* Als pil, wanneer de link de enige weg naar dat overzicht is.
   Op de homepage stond er eerst een rij tegels boven met dezelfde bestemming.
   Die is weg, dus moet deze link zelf laten zien dat er iets te tikken valt:
   platte tekst van 12px naast een kop wordt makkelijk overgeslagen. */
.gg-section-link--pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    padding: 8px 14px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-pill);
    background: var(--surface-card);
    color: var(--color-brand);
    box-shadow: var(--shadow-card);
}

.gg-section-link--pill i {
    font-size: 11px;
    transition: transform .15s ease;
}

.gg-section-link--pill:hover {
    text-decoration: none;
    border-color: var(--color-brand);
}

/* Het pijltje schuift een tik mee. Klein genoeg om niet druk te zijn, genoeg om
   te laten voelen dat het ergens naartoe gaat. */
.gg-section-link--pill:hover i { transform: translateX(2px); }

@media (prefers-reduced-motion: reduce) {
    .gg-section-link--pill i { transition: none; }
    .gg-section-link--pill:hover i { transform: none; }
}

/* ----------------------------------------------------------------- zoeken */
.gg-search {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-pill);
    padding: 4px 6px 4px 15px;
}

.gg-search:focus-within {
    border-color: var(--color-brand);
    box-shadow: 0 0 0 3px var(--color-brand-veil);
}

.gg-search > i {
    color: var(--color-brand);
    font-size: 15px;
}

.gg-search input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    font: inherit;
    font-size: 15px;
    color: var(--text-primary);
    padding: 9px 0;
    -webkit-appearance: none;
}

    .gg-search input:focus,
    .gg-search input:focus-visible {
        outline: none;
    }

.gg-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

.gg-search button {
    flex: 0 0 auto;
    border: 0;
    border-radius: var(--radius-pill);
    background: var(--color-brand);
    color: var(--text-on-brand);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    padding: 10px 17px;
    cursor: pointer;
}

.gg-search button:active { background: var(--color-brand-strong); }

/* wis-knop, alleen op het overzicht in gebruik */
.gg-search .gg-clear {
    background: transparent;
    color: var(--text-muted);
    font-size: 15px;
    padding: 8px 10px;
    display: none;
}

.gg-search .gg-clear.on { display: block; }
.gg-search .gg-clear:active { background: transparent; }

/* --------------------------------------------------------- categoriechips */
.gg-rail {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    margin: 0 -16px;
    padding: 2px 16px 8px;
    /* De rail bloedt 16px uit de contentkolom en de padding zet de eerste
       chip weer op de kantlijn. Scroll-snap rekent echter zonder die
       padding: bij het laden snapte de eerste chip tegen de schermrand en
       was de linkermarge weg. scroll-padding laat het snappen dezelfde
       kantlijn respecteren als de rest van de inhoud. */
    scroll-padding-inline: 16px;
}

.gg-rail::-webkit-scrollbar { display: none; }

/* De 2px padding-top van de rail is ruimte voor het indrukeffect van de
   chips, geen tussenruimte. Volgt de rail direct op een sectietitel, trek
   die 2px er dan af zodat de zichtbare afstand 10px blijft. */
.gg-eyebrow + .gg-rail { margin-top: -2px; }

.gg-chip {
    flex: 0 0 auto;
    scroll-snap-align: start;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-left: 3px solid var(--chipcolor, var(--color-brand));
    border-radius: var(--radius-chip);
    padding: 9px 15px;
    font-size: 13.5px;
    font-weight: 500;
    font-family: inherit;
    color: var(--text-primary);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: transform .12s ease;
}

.gg-chip:active { transform: scale(.97); }

.gg-chip i {
    font-size: 13px;
    color: var(--chipcolor, var(--color-brand));
}

.gg-chip--all { border-left-color: var(--color-structure); }
.gg-chip--all i { color: var(--color-structure); }

/* ingedrukte staat, gebruikt waar de chips filteren in plaats van linken */
.gg-chip.on {
    background: var(--chipcolor, var(--color-brand));
    border-color: var(--chipcolor, var(--color-brand));
    color: var(--text-on-brand);
}

.gg-chip.on i { color: var(--text-on-brand); }
.gg-chip--all.on { background: var(--color-structure); border-color: var(--color-structure); }

/* ==================================================================== de bon
   Een bon is een fysiek ding, dus de kaart gedraagt zich als een ticket:
   foto, perforatielijn met uitgeponste gaten, en het voordeel op een strook.

   De aangeleverde beelden zijn 2,242:1. Elke andere verhouding zou met
   object-fit: cover een deel van een al gecomponeerd beeld wegsnijden, dus de
   kaart volgt het beeld in plaats van omgekeerd. De brede kaart en de halve
   kaart hebben daarom dezelfde verhouding, alleen een andere kolombreedte.
   ========================================================================= */
.bon-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.bon--hero { grid-column: span 2; }

.bon {
    position: relative;
    display: block;
    background: var(--surface-card);
    border: .5px solid var(--border-subtle);
    border-radius: var(--radius-card);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    box-shadow: var(--shadow-card);
    transition: transform .12s ease;
}

.bon:active { transform: scale(.985); }

.bon-media {
    position: relative;
    display: block;
    aspect-ratio: var(--bon-ratio);
    background: var(--color-brand-tint);
}

@supports not (aspect-ratio: 1 / 1) {
    .bon-media {
        height: 0;
        padding-top: var(--bon-ratio-pct);
    }

    .bon-media img {
        position: absolute;
        inset: 0;
    }
}

.bon-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* De gele strook. Draagt nu Bonnen.Free, een echt gegeven, in plaats van
   een uit vrije tekst geraden label. Verschijnt dus alleen bij gratis bonnen. */
.bon-stub {
    position: absolute;
    left: 12px;
    bottom: 12px;
    background: var(--color-accent);
    color: var(--text-on-accent);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -.01em;
    padding: 4px 12px;
    border-radius: 4px;
    max-width: calc(100% - 24px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* de scheurlijn */
.bon-foot {
    position: relative;
    display: block;
    border-top: 1px dashed var(--border-perforation);
    padding: 11px 14px 13px;
}

.bon-title {
    display: block;
    font-size: 15.5px;
    font-weight: 700;
    line-height: 1.25;
    margin: 0;
}

.bon-company {
    display: block;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 3px 0 0;
}

/* De uitleg uit BonTraductions.Description, server-side ingekort. Twee
   regels op de brede kaart, want Title alleen is vaak te algemeen: negen
   Gentse bonnen heten gewoon "Korting". */
.bon-desc {
    /* let op de volgorde: -webkit-box moet als laatste staan, want
       -webkit-line-clamp werkt alleen met die display-waarde. Met block
       erna wint block en wordt het afkappen stilletjes overgeslagen. */
    display: block;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 12.5px;
    font-weight: 400;
    color: var(--text-muted);
    margin: 6px 0 0;
    line-height: 1.35;
}

/* ---- de halve kaarten: zelfde verhouding, kleinere typografie ----
   Het beeld is bij halve breedte maar zo'n 75px hoog, dus de voet moet mee
   krimpen, anders neemt tekst meer plek in dan de foto. */
.bon:not(.bon--hero) .bon-foot { padding: 9px 11px 11px; }
.bon:not(.bon--hero) .bon-title { font-size: 13px; }
.bon:not(.bon--hero) .bon-company { font-size: 10px; }
/* op een halve kaart is 168px te smal voor uitleg, daar dragen Title en
   zaaknaam het alleen */
.bon:not(.bon--hero) .bon-desc { display: none; }

.bon:not(.bon--hero) .bon-stub {
    left: 9px;
    bottom: 9px;
    font-size: 12px;
    padding: 3px 9px;
    max-width: calc(100% - 18px);
}

/* meerdere filialen met exact dezelfde bon */
.bon-locs {
    align-self: flex-start;
    margin: 6px 0 0;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 10.5px;
    font-weight: 600;
    color: var(--color-structure);
    background: var(--color-structure-tint);
    border-radius: var(--radius-pill);
    padding: 3px 9px;
}

/* de ponsgaten: de helft van elke cirkel wordt door de kaart afgesneden */
.bon-notch {
    position: absolute;
    top: calc(var(--notch-size) / -2);
    width: var(--notch-size);
    height: var(--notch-size);
    border-radius: 50%;
    background: var(--surface-notch);
    pointer-events: none;
}

.bon-notch--l { left: calc(var(--notch-size) / -2); }
.bon-notch--r { right: calc(var(--notch-size) / -2); }

/* ================================================================ de bonrij
   Dezelfde ticketgedachte als de bonkaart, maar op zijn kant: de perforatie
   loopt verticaal tussen beeld en tekst. Dat houdt een lange lijst leesbaar.

   Het beeld houdt de aangeleverde verhouding: de hoogte staat vast en de
   breedte volgt daaruit (86px x 2,242 = 193px), dus er wordt niets
   weggesneden.
   ========================================================================= */
.bon-row {
    position: relative;
    display: flex;
    align-items: stretch;
    height: var(--bon-row-h);
    background: var(--surface-card);
    border: .5px solid var(--border-subtle);
    border-radius: var(--radius-card-sm);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    box-shadow: var(--shadow-card);
    margin-bottom: 10px;
    transition: transform .12s ease;
}

.bon-row:active { transform: scale(.99); }

.bon-row-thumb {
    position: relative;
    flex: 0 0 auto;
    width: calc(var(--bon-row-h) * var(--bon-ratio-num));
    height: 100%;
    background: var(--color-brand-tint);
}

.bon-row-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.bon-row-body {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    border-left: 1px dashed var(--border-perforation);
    padding: 9px 12px 9px 13px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    overflow: hidden;
}

/* de ponsgaten, nu boven en onder een verticale naad */
.bon-row-body::before,
.bon-row-body::after {
    content: "";
    position: absolute;
    left: calc(var(--notch-size) / -2);
    width: var(--notch-size);
    height: var(--notch-size);
    border-radius: 50%;
    background: var(--surface-notch);
}

.bon-row-body::before { top: calc(var(--notch-size) / -2); }
.bon-row-body::after { bottom: calc(var(--notch-size) / -2); }

/* eerste regel: de titel, met eventueel het "3 zaken"-label erachter */
.bon-row-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}

.bon-row-title {
    flex: 1 1 auto;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bon-row-co {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-muted);
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Twee regels, niet één. Op één regel van zo'n 170px zie je ongeveer 25
   tekens, en dat is een fragment in plaats van informatie. Over twee regels
   is het er net genoeg om bonnen te onderscheiden die dezelfde titel dragen:
   7753 en 7754 heten beide "Korting" bij Print For You en verschillen alleen
   in hun uitleg. Twee regels passen precies binnen 86px, zie de mediaquery
   hieronder voor de smallere variant. */
.bon-row-desc {
    /* let op de volgorde: -webkit-box moet als laatste staan, want
       -webkit-line-clamp werkt alleen met die display-waarde. Met block
       erna wint block en wordt het afkappen stilletjes overgeslagen. */
    display: block;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 12px;
    color: var(--text-muted);
    line-height: 1.3;
    white-space: normal;
}

/* het gele Gratis-label op de duimnagel, zelfde plek als op de kaart */
.bon-row-thumb .bon-stub {
    left: 8px;
    bottom: 8px;
    font-size: 11px;
    padding: 2px 8px;
}

/* "3 zaken" hangt rechts op de titelregel, zodat de rij op drie
   tekstregels blijft en dus binnen --bon-row-h past */
.bon-row .bon-locs {
    margin: 0 0 0 auto;
    flex: 0 0 auto;
}

/* Op een smal scherm (360px) zou 193px beeld de tekst tot 134px knijpen.
   Een lagere rij geeft de tekst dan ruimte terug, met dezelfde verhouding. */
@media (max-width: 389px) {
    .bon-row { --bon-row-h: 72px; }
    .bon-row-title { font-size: 13.5px; }

    /* een rij van 72px heeft ruimte voor één regel uitleg, niet twee */
    .bon-row-desc { -webkit-line-clamp: 1; }
}

 /* ------------------------------------------------------------- advertentie
   Google Ad Manager-blok (Common/AdSlot.cs). Het geleverde beeld is 720x320;
   .gg-ad-frame houdt die echte maat en wordt met transform: scale() op de
   breedte van .gg-ad-box gezet. De hoogte van de box wordt door het script
   meegeschaald, zodat de pagina eronder gewoon aansluit. Tot de advertentie
   binnen is, houdt aspect-ratio de plek vrij (geen verspringende pagina);
   blijft het slot leeg, dan verbergt het script de hele sectie. */
 .gg-ad-box {
    position: relative;
    aspect-ratio: 720 / 320;
    overflow: hidden;
    border-radius: var(--radius-card);
    background: var(--surface-muted);
    }
    .gg-ad.is-filled .gg-ad-box {
        background: transparent;
    }
    .gg-ad-frame {
        position: absolute;
        top: 0;
        left: 0;
        width: 720px;
        height: 320px;
        transform-origin: 0 0;
    }
    .gg-ad-frame iframe {
        display: block;
    }
.gg-ad[hidden] {
    display: none;
}

/* -------------------------------------------------------------- lege staat */
.gg-empty {
    background: var(--surface-card);
    border: 1px dashed var(--border-perforation);
    border-radius: var(--radius-card);
    padding: 26px 20px;
    text-align: center;
}

.gg-empty h3 {
    font-family: var(--font-display);
    margin: 0 0 6px;
    font-size: 17px;
    font-weight: 700;
    color: var(--color-structure);
}

.gg-empty p {
    margin: 0 0 16px;
    font-size: 13.5px;
    color: var(--text-muted);
    line-height: 1.45;
}

.gg-empty a,
.gg-empty button {
    display: inline-block;
    background: var(--color-brand);
    color: var(--text-on-brand);
    border: 0;
    text-decoration: none;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    padding: 11px 22px;
    border-radius: var(--radius-pill);
    cursor: pointer;
}

/* ----------------------------------------------------------------- toegang */
a:focus-visible,
button:focus-visible,
input:focus-visible {
    outline: 2px solid var(--color-brand);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .gg-chip, .bon { transition: none !important; }
}
