/* ── Book flip animation ─────────────────────────────────── */
.book {
    width: 80vw;
    max-width: 1300px;
    height: 40vw;
    max-height: 650px;
    position: relative;
    -webkit-perspective: 1500px;
    perspective: 1500px;
    /* Een paar krappe, lichtgekleurde box-shadows (met een dun donker randje)
       gestapeld vóór de bestaande zachte drop-shadow suggereren de dikte van
       opeengestapelde pagina's die net onder het boek vandaan piepen — zonder
       dat is het alleen een platte rechthoek met een schaduw eronder. */
    box-shadow:
        3px 3px 0 0 #f2f2f2, 3px 3px 0 1px #d8d8d8,
        6px 6px 0 0 #f2f2f2, 6px 6px 0 1px #d8d8d8,
        9px 9px 0 0 #f2f2f2, 9px 9px 0 1px #d8d8d8,
        10px 10px 5px 0px rgba(0, 0, 0, 0.25);
    /* perspective triggert op zichzelf al een nieuwe stacking context, dus de
       z-index-waarden van .book .page hieronder golden alleen TEN OPZICHTE VAN
       ELKAAR, binnen .book — niet t.o.v. de navigatieknoppen daarbuiten. Zonder
       een eigen z-index hier bepaalt de DOM-volgorde de tekenvolgorde tussen
       .book en .btns, en kon een gehoverde knop (Bootstrap zet daar z-index:1
       op) alsnog over de flip-animatie heen clippen. Met een z-index hier wint
       .book altijd, ongeacht de knoppen-state. */
    z-index: 10;
}
.book .page {
    position: absolute;
    top: 0;
    width: 50%;
    padding: min(4vw, 65px);
    height: 100%;
    color: #3b3b3b;
    font-size: min(2vw, 32.5px);
    -webkit-transition: -webkit-transform .8s ease;
    transition: transform .8s ease;
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    -webkit-transform: rotateY(0deg);
    transform: rotateY(0deg);
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    z-index: 1;
    text-align: center;
    overflow: hidden;
}
.book .page.left  { left: 0; -webkit-transform-origin: right; transform-origin: right; overflow-wrap: break-word; }
.book .page.right { right: 0; -webkit-transform-origin: left; transform-origin: left; }
/* Dieptesuggestie bij de vouw (waar .page.left en .page.right samenkomen):
   een gewone box-shadow zit altijd rond de HELE box, dus ook langs de
   boven-/onder-/buitenrand van het boek — daarom hier i.p.v. box-shadow een
   gradient op een ::before, precies zo breed als de vouw diep moet lijken,
   die als enige aan de kant van de vouw (overflow:hidden op .book .page
   knipt 'm daar netjes af) naar transparant uitvaagt. Voor .page.left is dat
   de rechterrand, voor .page.right de linkerrand. */
.book .page.left::before,
.book .page.right::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: min(4vw, 20px);
    pointer-events: none;
    z-index: 1;
}
.book .page.left::before {
    right: 0;
    background: linear-gradient(to left, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0));
}
.book .page.right::before {
    left: 0;
    background: linear-gradient(to right, rgba(0, 0, 0, .25), rgba(0, 0, 0, 0));
}
.book .page.current { z-index: 2; }
.book .current.right.page.turn  { -webkit-transform: rotateY(-180deg); transform: rotateY(-180deg); }
.book .current.left.page.turn   { -webkit-transform: rotateY(180deg);  transform: rotateY(180deg); }
.book .next.left.page           { -webkit-transform: rotateY(180deg);  transform: rotateY(180deg); }
.book .next.left.page.turn      { -webkit-transform: rotateY(0deg);    transform: rotateY(0deg); }
.book .prev.right.page          { -webkit-transform: rotateY(-180deg); transform: rotateY(-180deg); }
.book .prev.right.page.turn     { -webkit-transform: rotateY(0deg);    transform: rotateY(0deg); }

.btns { text-align: center; width: 600px; margin: 20px 0; }
/* Navigatieknoppen zijn nu icoontjes i.p.v. tekst, dus geen vaste breedte meer
   nodig — gewoon laten meebewegen met de padding van .btn. */
#book_direction_btn_group .btn { width: 2.75rem; }
/* pointer-events:none i.p.v. alleen cursor:default, want dat laatste voorkomt
   niet dat de :hover-stijl van .btn-outline-secondary nog steeds toepast.
   Dezelfde breedte als de knoppen hierboven voorkomt dat de rij verspringt
   zodra het paginanummer van 1 naar 2 cijfers gaat (of terug). */
#book_page_indicator { cursor: default; pointer-events: none; width: 2.75rem; }
#book_page_indicator[disabled] { opacity: .65; }
/* Alleen relevant terwijl de cover getoond wordt, maar blijft ook in de
   book-weergave gewoon in de flow staan (enkel visibility:hidden, niet
   display:none) — anders verspringen cover-switch-btn en de navigatieknoppen
   elke keer dat je de cover opent/sluit, omdat .btns gecentreerd is op een
   vaste breedte. */
#toggle_crop_marks_btn { width: 2.75rem; margin-right: .5rem; }

/* ── Snijranden aan/uit ──────────────────────────────────────────────── */
.cover.hide-crop-marks::after,
.cover.hide-crop-marks::before { display: none; }

#canvas {
    height: 600px;
    width: 600px;
    background-color: #ffffff;
    cursor: default;
    border: 1px solid black;
}
img { max-width: 100%; }

.book-image-selector { cursor: pointer; }

/* Werkgebied rond de pagina: stickers mogen hierin tot over de paginarand
   worden gesleept/geschaald zodat de randen gevuld kunnen worden. Alles wat
   buiten de stippellijn (#page_grid) uitsteekt, wordt bij het opslaan
   automatisch afgeknipt omdat html2canvas alleen #page_grid zelf vastlegt.

   #page_grid_stage is de rechthoekige ruimte die overblijft in de flex-kolom
   (vult breedte + resterende hoogte) en is een size-container.
   #page_grid_bleed volgt nu simpelweg 100% breedte/hoogte van die ruimte
   (kan dus niet-vierkant zijn). #page_grid/#page_grid_boundary/#page_grid_mask
   blijven wél altijd vierkant en even groot als voorheen: die gebruiken
   cqw/cqh (t.o.v. #page_grid_stage, container-type:size) i.p.v. een
   percentage van hun (nu mogelijk niet-vierkante) ouder #page_grid_bleed. */
#page_grid_stage {
    width: 100%;
    flex: 1 1 auto;
    min-height: 0;
    container-type: size;
    display: grid;
    justify-items: center;
    align-items: start;
}
#page_grid_bleed {
    position: relative;
    width: 100%;
    height: 100%;
    background: #fff;
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
    /* Horizontaal gecentreerd, verticaal tegen de bovenkant: #page_grid krijgt
       daarnaast hieronder een margin-top zodat er nog een substantiële,
       zichtbare bleed-strook boven de pagina overblijft (dezelfde 10%-marge
       die er ook was toen de bleed nog z'n eigen vierkante grootte had). */
    justify-items: center;
    align-items: start;
}
/* Wit doorschijnend "gat"-overlay: dekt de hele (nu mogelijk niet-vierkante)
   bleed af, behalve het middelste gedeelte dat exact samenvalt met
   #page_grid/#page_grid_boundary. Omdat #page_grid_mask zelf altijd exact zo
   groot is als #page_grid_bleed (100% × 100%), komt 1cqw/1cqh hier precies
   overeen met 1% van de mask — daarom kan de uitsparing gewoon met dezelfde
   cqw/cqh-halve-zijde (--pg-half) berekend worden als de breedte/hoogte van
   #page_grid hieronder, en blijft hij altijd exact uitlijnen, ongeacht de
   (nu losstaande) verhouding tussen bleed en page_grid. Zo lijkt het alsof
   het deel van een sticker dat in de bleed steekt wit is "afgesneden",
   zonder dat #page_grid zelf ooit wordt aangeraakt. clip-path i.p.v.
   overflow:hidden op #page_grid_bleed, zodat het label (dat net búiten de
   page_grid-box boven de stippellijn hangt) niet per ongeluk wordt
   afgeknipt. */
#page_grid_mask {
    --pg-half: min(40cqw, 40cqh);
    --pg-top-gap: min(10cqw, 10cqh);
    grid-area: 1 / 1;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, .75);
    /* Uitsparing horizontaal gecentreerd, maar verticaal tegen de bovenkant
       (--pg-top-gap) i.p.v. 50% — moet in de pas blijven met de
       margin-top hieronder op #page_grid_boundary/#page_grid. */
    clip-path: polygon(
        evenodd,
        0% 0%, 100% 0%, 100% 100%, 0% 100%, 0% 0%,
        calc(50% - var(--pg-half)) var(--pg-top-gap),
        calc(50% - var(--pg-half)) calc(var(--pg-top-gap) + var(--pg-half) * 2),
        calc(50% + var(--pg-half)) calc(var(--pg-top-gap) + var(--pg-half) * 2),
        calc(50% + var(--pg-half)) var(--pg-top-gap),
        calc(50% - var(--pg-half)) var(--pg-top-gap)
    );
    pointer-events: none;
    z-index: 500;
}
#page_grid_boundary {
    grid-area: 1 / 1;
    position: relative;
    aspect-ratio: 1 / 1;
    width: min(80cqw, 80cqh);
    margin-top: min(10cqw, 10cqh);
    border: 1.5px dashed #448c74;
    pointer-events: none;
    z-index: 1000;
}
#page_grid_boundary_label {
    /* bottom:100% t.o.v. #page_grid_boundary zet het label altijd exact op de
       bovenrand van de (responsive) stippellijn, ongeacht diens grootte. */
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    margin-bottom: .4rem;
    text-align: center;
    /* cqw = t.o.v. #page_grid_stage (container-type:size), schaalt dus mee met het
       scherm; clamp() houdt de tekst binnen leesbare grenzen aan beide uitersten. */
    font-size: clamp(10px, 2.2cqw, 16px);
    color: #448c74;
    line-height: 1;
}
#page_grid {
    grid-area: 1 / 1;
    position: relative;
    aspect-ratio: 1 / 1;
    width: min(80cqw, 80cqh);
    margin-top: min(10cqw, 10cqh);
    background: #c1c1c1;
}
.page-item {
    display: inline-block;
    position: absolute;
    margin: 0;
    cursor: pointer;
    /* outline i.p.v. border: telt niet mee in de layout-box, dus beïnvloedt
       de breedte/hoogte niet die rescalePageItems() bijhoudt (een border zou,
       door de globale box-sizing:border-box reset, bij elke resize-cyclus
       4px van de bijgehouden grootte laten "weglekken" — vandaar de bug
       waarbij stickers bij herhaald in-/uitzoomen van het scherm steeds
       kleiner werden). */
    outline: 2px dashed transparent;
    outline-offset: -2px;
}
/* white-space:nowrap staat al inline op de tekst-span (voorkomt wrappen naar
   een 2e regel); overflow:hidden hier is een extra vangnet zodat een tekst
   die tijdens een zeer snelle/extreme resize (bv. venster naar ~1px en
   meteen weer terug) héél even niet meeschaalt, niet zichtbaar buiten zijn
   eigen box uitsteekt. */
/* Bewust GEEN overflow:hidden op tekst-stickers: (1) de draaiknop
   (ui-rotatable-handle) steekt buiten de box en werd anders afgeknipt,
   (2) html2canvas' tekstmeting wijkt net af van de browser waardoor het
   einde van de tekst in de export afgeknipt werd, en (3) uithalen van
   sierlettertypen mogen buiten de (randloze) box vallen. De box volgt de
   tekst toch al strak via sizeTextPageItem + de font-hoogteverhouding. */
.page-item .ui-resizable-handle,
.page-item .ui-rotatable-handle  { display: none !important; }
.page-item:hover .ui-resizable-handle,
.page-item.selected .ui-resizable-handle { display: block !important; }
.page-item:hover .ui-rotatable-handle,
.page-item.selected .ui-rotatable-handle { display: block !important; background-color: #2d2d2d; }
.page-item:hover,
.page-item.selected { outline-color: lightgrey; }

.list-group-item        { cursor: grab; }
.list-group-item:active { cursor: grabbing; }
/* De knoppen staan (in de HTML) vóór deze tekst en zijn float:right — daardoor
   krimpt dit blok (via overflow:hidden, dat ook een nieuwe block formatting
   context opent) automatisch tot de ruimte die naast de knoppen overblijft,
   i.p.v. dat lange tekst de knoppen omlaag duwt. white-space:nowrap +
   text-overflow:ellipsis knipt de tekst dan netjes af met "...". */
.list-group-item .layer-label {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.asColorPicker-dropdown { max-width: 260px !important; }
.flipped-img { transform: scale(-1, 1) !important; }
.apply-font  { overflow-wrap: break-word; }

/* ── Editor layout ───────────────────────────────────────── */
/* vh (niet vw!): de sectie moet binnen de schermHOOGTE passen. Met vw werd
   de pagina op brede/lage schermen hoger dan het venster en dus scrollbaar,
   met lege ruimte onder de sectie. */
.editor-section { margin-top: 4rem; overflow: hidden; }
.book-area      { padding: 1rem 1.5rem 0; }
.book-controls  { width: 80vw; margin: 1.6vw auto .75rem; text-align: center; }
/* Vaste breedte i.p.v. fit-content: "Bekijk Cover" en "Sluit Cover" zijn niet
   even lang, dus met fit-content verspringt de hele knoppenrij bij elke klik. */
.cover-switch-btn { width: 9rem; }
/* Bewust géén min-width op de kaart: de rijen erin hebben flex-wrap, dus bij
   een te klein venster breken de groepen naar een volgende regel — een
   min-width (fit-content) zou de kaart breed houden en dat wrappen juist
   tegenhouden. */
.settings-card  { width: 80vw; max-width: 1300px; margin: .75rem auto 0; border-radius: .75rem !important; }

/* Settings toolbar helpers */
.settings-label { display: block; font-size: .72rem; font-weight: 600; color: #6b7280; text-transform: uppercase; letter-spacing: .04em; margin-bottom: .3rem; }
/* Voor bijzinnen in een settings-label, zoals "(Optioneel)": lichter en minder zwaar */
.settings-label-muted { color: #b0b6c0; font-weight: 500; }
.format-label   { display: inline-flex; flex-direction: row; align-items: center; gap: .5rem; padding: .5rem .75rem; line-height: 1.3; overflow: hidden; white-space: normal; }
.format-label-text { display: flex; flex-direction: column; align-items: flex-start; white-space: nowrap; }
.product-img    { max-height: 3.5rem; max-width: 100%; width: auto; height: auto; }

/* ── Book text ───────────────────────────────────────────── */
.book-text-center {
    font-family: 'Kalam', cursive;
    position: relative;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}
#hint_click_text {
    display: none;
    font-size: min(1.2vw, 19.5px);
    position: absolute;
    bottom: 1rem;
    margin: auto;
    left: 0;
    right: 0;
}
#book_text_save_button { display: none; margin-top: min(7vw, 143px); }

.placeholder-inner { height: 100%; cursor: pointer; }
.book-image-hint   { font-size: min(1.6vw, 26px) !important; top: 70%; }

/* Schaal-wrapper om boek + cover: de scale zelf (en de bijpassende hoogte)
   zet rescaleBookArea() in book_editor.js; hier alleen het schaal-anker —
   vanaf de bovenkant, horizontaal gecentreerd, zodat het boek onder de
   knoppenrij blijft hangen en het menu omhoog kan schuiven. */
#book_scale_wrap { transform-origin: top center; }

/* ── Cover ───────────────────────────────────────────────── */
.cover {
    margin: auto;
    background-color: white;
    width: 80vw;
    max-width: 1300px;
    height: 40vw;
    max-height: 650px;
    position: relative;
    perspective: 1500px;
    box-shadow: 10px 10px 5px 0px rgba(0, 0, 0, 0.25);
    display: none;
}
.cover::after {
    content: '';
    position: absolute;
    inset: 7% 3.5%;
    border: 2px dashed #448c74;
    pointer-events: none;
    z-index: 10;
}
.cover::before {
    content: 'LET OP: GESCHATTE SNIJRANDEN';
    position: absolute;
    top: 3%;
    left: 3%;
    font-size: 16px;
    color: #448c74;
    pointer-events: none;
    z-index: 11;
    line-height: 1;
}
/* Verhoudingen 1-op-1 met het drukbestand (templates/book/cover.html):
   achterkant 49,375% + rug 1,25% + voorkant 49,375%. Op de 80vw-cover is de
   rug dus 1vw (1,25% van 80vw; cap 16.25px = 1,25% van 1300px). De kolommen
   hoeven niet exact gezet: het zijn .col's (flex-basis 0) die de restruimte
   gelijk verdelen, dus elk automatisch 39,5vw = 49,375%. */
.cover-col          { height: min(40vw, 650px); padding-right: 0; position: relative; overflow: hidden; }
.cover-front-col    { height: min(40vw, 650px); padding-left: 0; position: relative; overflow: hidden; }
/* 3D-rug: het boek "ligt op z'n buik", dus de rug is een verhoogde, ronde
   richel. Twee ingrediënten: (1) een slagschaduw aan weerszijden die over de
   voor- en achterkant valt (iets sterker rechts, passend bij de
   licht-van-linksboven van de bestaande .cover-schaduw), waardoor de rug
   bóven de covers lijkt te liggen; (2) op ::after een cilinder-shading —
   donkere flanken, lichte kern — die de ronding suggereert. z-index 2 zodat
   rug + schaduw over de halftoon-strips van de buurkolommen heen tekenen.
   Alleen visueel; verhoudingen (1,25% rugbreedte) blijven exact print. */
.cover-spine {
    height: min(40vw, 650px);
    max-width: min(1vw, 16.25px) !important;
    padding: 0;
    position: relative;
    z-index: 2;
}
/* De richel is visueel breder dan de rug-div: ::after steekt aan beide
   kanten uit over de covers heen (negatieve inset), zodat het 3D-effect
   breder oogt zonder de (print-correcte) rugbreedte zelf aan te raken.
   De slagschaduw zit daarom ook hier en niet op de div. */
.cover-spine::after {
    content: '';
    position: absolute;
    inset: 0 calc(-1 * min(.14vw, 2.3px));
    pointer-events: none;
    box-shadow:
        min(.12vw, 2px) 0 min(.45vw, 7px) rgba(0, 0, 0, .18),
        calc(-1 * min(.09vw, 1.5px)) 0 min(.45vw, 7px) rgba(0, 0, 0, .12);
    background: linear-gradient(to right,
        rgba(47, 55, 66, .16) 0%,
        rgba(47, 55, 66, .06) 22%,
        rgba(255, 255, 255, .35) 46%,
        rgba(255, 255, 255, .35) 54%,
        rgba(47, 55, 66, .07) 78%,
        rgba(47, 55, 66, .18) 100%);
}
.cover-image-wrapper { height: 100%; width: 100%; margin: auto; }

/* Zelfde halftoon-overgang naar de witte rug als op de gedrukte cover
   (templates/book/cover.html gebruikt exact dezelfde PNG's): witte dots die
   dichtlopen richting de rug. Strips zijn even breed als de rug
   (.cover-spine), dus de totale overgangszone incl. rug is 3x de rugbreedte
   — daarmee is de preview een eerlijke representatie van het drukwerk.
   background-size 100% auto (i.p.v. 100% 100%): de PNG is 1:42, de strip op
   scherm 1:25 — meestretchen zou de dots tot ovalen vervormen; de hoogte
   mag gewoon afkappen want het patroon is verticaal uniform. */
.cover-col::before,
.cover-front-col::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: min(1vw, 16.25px); /* altijd gelijk aan de rugbreedte (.cover-spine) */
    background-size: 100% auto;
    background-repeat: no-repeat;
    pointer-events: none;
    z-index: 1;
}
.cover-col::before {
    right: 0;
    background-image: url('https://mynovelist.s3.amazonaws.com/media/cover_fold_dots_left.png');
}
.cover-front-col::before {
    left: 0;
    background-image: url('https://mynovelist.s3.amazonaws.com/media/cover_fold_dots_right.png');
}
.cover-image-hint   { font-size: 1rem !important; top: 80%; cursor: pointer; }
.cover-logo         { width: min(6.4vw, 104px); height: min(6.4vw, 104px); }

/* Gebaseerd op de uiteindelijke print-opmaak (templates/book/cover.html): daar
   staat de titel in een apart wrapper-element dat centreert + de writing-mode
   zet, en een <p> eronder met alleen typografie. Hier op één element gecombineerd,
   want de editor heeft geen aparte wrapper-div. letter-spacing is een em-waarde
   (i.p.v. de letterlijke 1mm uit het printdocument) omdat de font-size hier
   responsive/vw-gebaseerd is: 1mm t.o.v. de 4.4mm print-fontsize ≈ 0.23em, en
   met em schaalt de tracking netjes mee i.p.v. bij een klein scherm relatief
   te breed te worden. */
#book_title_placeholder {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1; /* boven de cilinder-shading van .cover-spine::after, anders vervagen de letters */
    -webkit-writing-mode: vertical-rl;
    writing-mode: vertical-rl;
    white-space: nowrap;
    margin: 0;
    /* Zelfde verhouding als print: 4,4mm font op 478mm breedte = 0,92% van de
       cover → 0.74vw van 80vw (cap: 12px bij de 1300px-cover). Groter zou uit
       de (nu print-correcte, smallere) rug steken. */
    font-size: min(.74vw, 12px);
    /* Print heeft letter-spacing 1mm op een 4,4mm-font = 0.227em; als em
       schaalt hij hier automatisch mee met de responsive font-size. */
    letter-spacing: .227em;
    line-height: 1.25;
    font-family: "Helvetica", "Arial", sans-serif;
    -webkit-font-smoothing: antialiased;
}

/* Voor het wisselen van boek- naar cover-instellingen in het settings-menu
   (switch_cover_book in book_editor.js). Bewust géén Bootstrap .d-none: de
   kolommen zijn .d-flex en die utility staat in theme.css ná .d-none, dus
   .d-none verliest daarvan. Dit bestand laadt ná theme.css en wint dus wel. */
.setting-hidden { display: none !important; }
/* Voor de boek-opties in cover-modus: onzichtbaar mét behoud van hun BREEDTE
   (zodat de Boek Titel-input in beide modi exact even breed blijft), maar
   zónder hun hoogte — anders houdt de verborgen Uitlijning/Afbeeldingen-kolom
   rij 1 onnodig hoog en hangt er lege ruimte boven rij 2. height:0 laat de
   breedte intact (die volgt uit de content), overflow:hidden knipt de rest
   weg en de negatieve margin compenseert de flex-gap boven het item. */
.setting-invisible {
    visibility: hidden !important;
    height: 0 !important;
    overflow: hidden;
    margin-top: -1rem;
}

/* Kleurkiezers in het cover-menu: dezelfde asColorPicker als elders op de
   site (tekst-sticker-modal, illustratie-achtergrond), maar de kale
   18×20px-trigger van de plugin is hier opgemaakt als pill in de huisstijl —
   zelfde hoogte en rand als de .form-control-sm van "Boek Titel" ernaast. */
.cover-color-picker .asColorPicker-wrap { display: block; }
.cover-color-picker .asColorPicker-trigger {
    display: block;
    width: 6.5rem;
    height: 2.125rem;
    padding: .3rem;
    background: #fff;
    border: var(--ar-border-width, 1px) solid var(--ar-gray-400, #cad0e0);
    border-radius: 50rem;
    cursor: pointer;
    transition: border-color .2s ease-in-out;
}
.cover-color-picker .asColorPicker-trigger:hover { border-color: var(--ar-gray-500, #9397ad); }
.cover-color-picker .asColorPicker-trigger span {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50rem;
    /* Subtiel binnenrandje, anders is de witte rug-default onzichtbaar op de kaart */
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08);
}
/* Vóór init is dit een kale hex-input: niet tonen. Na init zit de input in
   .asColorPicker-wrap (dan geldt deze child-selector niet meer) en verbergt
   de plugin 'm zelf via hideInput. Laadt de plugin niet, dan toont de
   JS-fallback (catch in book_editor.js) de input alsnog. */
.cover-color-picker > input { display: none; }

.cover-title-size-range { width: 11rem; }

/* Beide lettertype-dropdowns klappen naar bóven uit: ze staan onderin de
   settings-kaart en .editor-section heeft overflow:hidden, dus een naar
   beneden uitklappende lijst valt buiten de sectie en wordt afgeknipt.
   Boven de knop (richting het boek/de cover) is ruimte genoeg. z-index
   boven de kaart-inhoud zodat de lijst over de andere opties heen tekent. */
#font-picker ul,
#font-picker-covertitle ul {
    top: auto;
    bottom: 100%;
    z-index: 5;
}

/* Rij 2 van het cover-menu: de drie controls (switch, kleur-pill, slider)
   hebben elk een andere natuurlijke hoogte. Elk krijgt hetzelfde slot met de
   hoogte van de kleur-pill en centreert daarbinnen verticaal — met de labels
   bovenaan (align-items-start op de rij) ligt dan alles op één lijn. */
.cover-title-control {
    height: 2.125rem;
    display: flex;
    align-items: center;
}

/* Titel op de voorkant van de cover (optioneel, zie "Titel tonen" in het
   cover-menu). Kleur en font-size worden vanuit book_editor.js gezet
   (applyCoverTitle). top 12% houdt hem binnen de geschatte snijranden
   (.cover::after zit op inset 7%). Bewust left+right i.p.v. left:50% +
   translateX(-50%): een absoluut element krijgt bij left:50% maar een halve
   kolom shrink-to-fit-breedte en brak daardoor veel te vroeg af. 9,5% aan
   weerszijden = 81% breed: net iets binnen de groene snijlijn (3,5% van de
   hele cover = ±7% van deze kolom); centreren doet text-align.
   pointer-events none: klikken gaat door naar de afbeelding eronder
   (afbeelding-modal openen). */
#cover_title_placeholder {
    position: absolute;
    top: 12%;
    left: 9.5%;
    right: 9.5%;
    z-index: 2;
    margin: 0;
    text-align: center;
    word-break: break-word;
    pointer-events: none;
    line-height: 1.2;
    /* Geen font-family hier: die komt van de Lettertype Titel-kiezer via de
       .apply-font-covertitle-klasse (FontPicker pickerId 'covertitle'), en een
       id-regel zou daar altijd van winnen. */
    -webkit-font-smoothing: antialiased;
    text-shadow: 0 0 min(.6vw, 10px) rgba(255, 255, 255, .35);
}
#back_cover_credits {
    position: absolute;
    width: min(6.4vw, 104px);
    height: min(6.4vw, 104px);
    text-align: center;
    cursor: pointer;
    top: 20%;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.6);
    left: calc(min(16vw, 260px)*1.1);
}

/* ── Book format ─────────────────────────────────────────── */
.product-img { height: 5rem; }

/* ── Image modal ─────────────────────────────────────────── */
.upload-sidebar { border-right: 1px solid lightgrey; padding: 0 2rem 1rem 1rem; }

/* Upload/illustratie-editor keuzekaarten: hoogte groeit/krimpt mee met het
   scherm (clamp op vw), maar blijft rond de 10rem op een normaal beeldscherm.
   Standaard is alleen de titel zichtbaar; bij hover wisselt die van plek met
   de uitlegtekst (zie .upload-option-title/-hint hieronder) — de kaart zelf
   verandert niet van formaat. De linker afbeelding is vierkant (aspect-ratio
   1/1 t.o.v. de kaarthoogte) en zonder eigen rand. */
.upload-option-card {
    cursor: pointer;
    height: clamp(5rem, 9vw, 10rem);
    overflow: hidden;
    border-radius: 1rem;
    transition: box-shadow .15s ease, border-color .15s ease;
}
.upload-option-card:hover {
    border-color: #448c74;
    box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .08);
}
/* De hele kaart is al cursor:pointer, maar de stretched-link (die de
   klikbare laag over de hele kaart legt, incl. boven de upload-label) moet
   dit ook expliciet zetten — een <label> krijgt van de browser zelf geen
   pointer-cursor, dus zonder deze regel viel dat op die kaart terug op de
   standaardcursor. */
.upload-option-card .stretched-link { cursor: pointer; }
/* Het icoonvlak is vierkant zolang er ruimte is, maar mag krimpen (flex-
   shrink) zodra de titel anders afgeknipt zou worden — de titel is via z'n
   nowrap-minbreedte de maatgevende partij (zie .upload-option-text). De
   min-width voorkomt dat het vlak helemaal verdwijnt. */
.upload-option-icon {
    position: relative;
    aspect-ratio: 1 / 1;
    height: 100%;
    flex: 0 1 auto;
    min-width: 2.75rem;
    background: #eef0f2;
    color: #448c74;
    container-type: size;
}
/* Zelfde formaat voor alle iconen; schaalt mee (cqw) als het vlak smaller
   wordt dan vierkant, zodat het glyph nooit uit het vlak steekt. */
.upload-option-icon i { font-size: min(clamp(1.5rem, 2.4vw, 2.25rem), 55cqw); }
/* Illustratie-editor-kaart: 3 gelijke iconen in een driehoeksverhouding
   i.p.v. 1 groot icoon met 2 kleine badges erbovenop. */
.upload-option-icon-trio i { position: absolute; }
.upload-option-icon-trio .ai-image      { top: 30%;    left: 50%; transform: translate(-50%, -50%); }
.upload-option-icon-trio .ai-sticker    { bottom: 30%; left: 30%; transform: translate(-50%, 50%); color: #e2725b; }
.upload-option-icon-trio .ai-paint-roll { bottom: 30%; right: 30%; transform: translate(50%, 50%); color: #d9a441; }
/* Titel en uitlegtekst gestapeld op dezelfde plek (grid-area 1/1): standaard
   zie je de titel, bij hover/focus vervaagt die en verschijnt de uitleg
   ervoor in de plaats — de kaart houdt exact dezelfde hoogte.
   flex-basis 0 (niet auto!): anders telt de max-content van de hinttekst mee
   in de krimpverdeling en krimpt elk icoonvlak anders. Met basis 0 krijgt de
   tekst precies z'n min-width (de meetlat, in elke kaart gelijk) en gaat
   álle resterende krimp naar het icoonvlak — overal even veel.
   overflow: hidden i.p.v. auto: nooit scrollbars in de kaart; een hint die
   op een klein scherm net niet past wordt afgeknipt. */
.upload-option-text {
    display: grid;
    align-items: center;
    padding: .25rem .75rem;
    flex: 1 1 0;
    min-width: min-content;
    overflow: hidden;
}
/* Onzichtbare meetlat met álle kaarttitels (zelfde font-stijl als de echte
   titel): geeft elk tekstblok dezelfde min-content-breedte — die van de
   breedste titel — zodat de icoonvlakken van de drie kaarten altijd even
   breed zijn. height: 0 zodat de meetlat de kaarthoogte niet beïnvloedt. */
.upload-option-title-sizer {
    grid-area: 1 / 1;
    height: 0;
    visibility: hidden;
    font-weight: 600;
    font-size: clamp(.8rem, 1.4vw, 1rem);
    white-space: nowrap;
    pointer-events: none;
}
/* Altijd 1 regel; geen ellipsis — past de titel niet, dan levert het
   icoonvlak breedte in (zie .upload-option-icon). */
.upload-option-title {
    grid-area: 1 / 1;
    display: block;
    font-weight: 600;
    font-size: clamp(.8rem, 1.4vw, 1rem);
    white-space: nowrap;
    transition: opacity .2s ease;
}
.upload-option-hint {
    grid-area: 1 / 1;
    display: block;
    opacity: 0;
    font-size: .82rem;
    line-height: 1.4;
    color: #9a9a9a;
    transition: opacity .2s ease;
    pointer-events: none;
}
.upload-option-card:hover .upload-option-title,
.upload-option-card:focus-within .upload-option-title { opacity: 0; }
.upload-option-card:hover .upload-option-hint,
.upload-option-card:focus-within .upload-option-hint { opacity: 1; }
.gallery-col    { padding: 0 0 1rem 2rem; }
.gallery-img    { background-color: whitesmoke; }
/* Placeholder-formaat zolang een lazy afbeelding (data-src, zie
   initGalleryLazyLoad) nog niet geladen is: zonder dit klapt een src-loze
   <img> dicht naar 0px hoogte, waardoor álle kaarten tegelijk "in beeld"
   zouden zijn en de observer alsnog alles in één keer zou laden. Vierkant
   is het juiste formaat: AI-generaties zijn dat altijd al en uploads gaan
   door de vierkante cropper. */
.gallery-img[data-src] { width: 100%; aspect-ratio: 1 / 1; }
/* Lege staat van de galerij: uitnodiging om te beginnen i.p.v. een
   placeholder-plaatje. Gestileerd als "drop zone" (gestippelde rand). */
.gallery-empty-state {
    padding: 4rem 2rem;
    border: 2px dashed #d7dde2;
    border-radius: 1rem;
    text-align: center;
    color: #858c97;
}
.gallery-empty-state i { display: block; font-size: 3rem; color: #b4bbc3; margin-bottom: 1rem; }
.gallery-empty-state h5 { color: #576071; margin-bottom: .5rem; }
.gallery-empty-state p { max-width: 34rem; margin: 0 auto; font-size: .95rem; line-height: 1.6; }
.quality-badge  { position: absolute; bottom: 10px; left: 10px; display: none; }
.gallery-delete-btn {
    position: absolute;
    top: 8px;
    right: 8px;
    opacity: 0;
    pointer-events: none;
    transition: opacity .15s ease-in-out;
}
.zoom-effect-wrapper:hover .gallery-delete-btn {
    opacity: 1;
    pointer-events: auto;
}
/* Toont bij welke boekpagina een AI-gegenereerde galerij-afbeelding hoort
   (alleen aanwezig op afbeeldingen die uit een pagina-job komen, niet op
   uploads of personage-sheets). */
.illu-page-pill {
    position: absolute;
    top: 8px;
    left: 8px;
    background: rgba(255, 255, 255, .85);
    color: #2f4a3f;
    font-size: .7rem;
    font-weight: 600;
    padding: .2rem .6rem;
    border-radius: 50rem;
    pointer-events: none;
}
/* Afbeeldingen die bij de OPENSTAANDE pagina horen: pill in de primaire
   sitekleur zodat ze direct opvallen (gezet in updateGalleryPagePills()). */
.illu-page-pill-current {
    background: #448c74;
    color: #fff;
    box-shadow: 0 .15rem .4rem rgba(56, 111, 91, .35);
}

/* ── Illustration editor ─────────────────────────────────── */
/* Sidebar als flex-kolom: de vaste onderdelen (toevoegen-knoppen, zoekveld)
   bovenaan, en de thema's/stickerlijst vullen de resterende hoogte met hun
   eigen scroll — i.p.v. de oude vw-gebaseerde hoogtehacks. */
.illus-sidebar {
    border-right: 1px solid #e3e9ef;
    padding: 0rem 1.25rem 1rem 1rem;
    height: 100%;
    display: flex;
    flex-direction: column;
    min-height: 0;
}
.illus-main-col   { border-right: 1px solid #e3e9ef; height: 100%; display: flex; flex-direction: column; }
.layers-col       { padding: 0 1rem 1rem 2rem; }
.output           { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.layers-hint      { color: #858c97; }

/* "Toevoegen": drie rustige witte keuzeknoppen in de huisstijl — afgeronde
   kaart, groen getint icoonvlak, titel + korte hint, subtiele hover. */
/* Compact 2-rijen-grid: Afbeelding + Illustratie naast elkaar, Tekst
   (illus-add-btn-wide) eronder over de volle breedte. De uitlegzinnetjes
   zitten als title-tooltip op de knoppen. */
.illus-add-group { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; }
.illus-add-btn {
    display: flex;
    align-items: center;
    gap: .5rem;
    min-width: 0;
    padding: .4rem .55rem;
    background: #fff;
    border: 1px solid #e3e9ef;
    border-radius: .75rem;
    text-align: left;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.illus-add-btn-wide { grid-column: 1 / -1; }
.illus-add-btn:hover { border-color: #448c74; box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .06); }
.illus-add-icon {
    flex: 0 0 auto;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #f0f7f4;
    color: #448c74;
    border-radius: .55rem;
    font-size: 1rem;
}
.illus-add-text { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.illus-add-text b { font-size: .85rem; color: #576071; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.illus-divider { margin: 1.1rem 0 .9rem; border-color: #e3e9ef; opacity: 1; }

/* Sticker-zoekveld */
.sticker-search-group { padding: 0; margin-bottom: .75rem; }
.sticker-search-group .form-control { border-color: #e3e9ef; }
.sticker-search-group .form-control:focus { border-color: #448c74; box-shadow: none; }

/* Thema's: wrappende chips die de resterende kolomhoogte vullen (eigen
   scroll). De ids/het toon-verberg-gedrag (#sticker_themes <-> #sticker_row,
   via jQuery .show()/.hide()) is ongewijzigd. */
#sticker_themes { flex: 1 1 auto; min-height: 0; }
.sticker-themes-col { height: 100%; }
.sticker-theme-row {
    height: 100%;
    overflow-y: auto;
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    align-content: flex-start;
    padding-right: .25rem;
}
.theme-btn {
    background: #fff;
    border: 1px solid #e3e9ef;
    color: #576071;
    border-radius: 2rem;
    padding: .3rem .8rem;
    font-size: .8rem;
    line-height: 1.2;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.theme-btn:hover { border-color: #448c74; background: #f0f7f4; color: #2f4a3f; }

/* Stickers van het gekozen thema: kopregel (hint + sluitkruisje) met
   daaronder de scrollende stickerlijst. */
.sticker-row { display: none; flex: 1 1 auto; min-height: 0; }
.sticker-row-head { display: flex; align-items: center; justify-content: space-between; }
.sticker-hint { font-style: normal; font-size: .78rem; color: #858c97; }
.sticker-row-head .btn-close { font-size: .7rem; }
.sticker-by-theme { overflow-y: auto; height: calc(100% - 2.2rem); }
.sticker-by-theme .col-4 { padding: .3rem; }
.sticker-by-theme img {
    width: 100%;
    background: #f7f9fc;
    border: 1px solid #e3e9ef;
    border-radius: .6rem;
    padding: .35rem;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.sticker-by-theme img:hover { border-color: #448c74; box-shadow: 0 .25rem .5rem rgba(0, 0, 0, .06); }

#background_color { width: 5rem; }
/* Alleen zichtbaar (via updatePPIWarning) zolang er een afbeelding onder de
   350 PPI op het canvas staat — en dan als echte waarschuwing in rood. */
#PPI_text         { color: #ed5050; display: none; }

/* ── Tekst-sticker modal ─────────────────────────────────── */
#raw_text_upload_modal .modal-content { border: 0; border-radius: 1rem; box-shadow: 0 1rem 3rem rgba(0, 0, 0, .15); }
#raw_text_upload_modal .modal-header  { border-bottom: 0; gap: .6rem; align-items: center; padding-bottom: .35rem; }
#raw_text_upload_modal .modal-body    { padding-top: .5rem; }
#raw_text_upload_modal .modal-title   { font-size: 1.05rem; }
.text-sticker-submit { margin-top: 1rem; }
#page_layers      { overflow-y: scroll; height: 40vw; }

/* ── Toast ───────────────────────────────────────────────── */
.editor-toast { position: fixed; top: 6rem; right: 6rem; z-index: 1100; }

/* Stapel voor de AI-pagina-toasts: meerdere pagina's kunnen nu tegelijk
   afronden, dus dit is geen los toast-element meer maar een kolom die er
   zoveel kan tonen als er tegelijk klaar/mislukt zijn. De kinderen zelf
   krijgen geen eigen position (dat doet .editor-toast-stack al). */
.editor-toast-stack { display: flex; flex-direction: column; gap: .5rem; align-items: flex-end; }

/* Blijvende "er loopt nog iets op de achtergrond"-indicator (i.t.t. de
   toasts hierboven, die zichzelf na een tijdje verbergen) — linksonder,
   zodat 'ie nooit met de toasts rechtsboven overlapt. */
.illu-bg-progress {
    position: fixed;
    left: 1.5rem;
    bottom: 1.5rem;
    z-index: 1090;
    display: flex;
    align-items: center;
    gap: .6rem;
    background: #fff;
    border: 1px solid rgba(68, 140, 116, .25);
    color: #2f4a3f;
    border-radius: 50rem;
    padding: .5rem 1.1rem .5rem .65rem;
    font-size: .85rem;
    font-weight: 500;
    box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .08);
    cursor: pointer;
}
.illu-bg-progress .spinner-border { width: 1rem; height: 1rem; color: #448c74; }

/* ── book_check.html specific ───────────────────────────── */
/* Hide number input spinners */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    margin: 0;
}

/* Email / phone icon padding */
.input-icon-lg  { padding-left: 2.5rem; }
.input-icon-sm  { padding-left: 1.8rem; }
.input-uppercase { text-transform: uppercase; }

/* Booking card */
.check-card { margin: 3rem; padding: 1rem 2rem; }

/* Book controls bar */
.check-btns { margin: auto; margin-top: 2rem; }

/* Price row */
.price-tax  { font-size: small !important; }

/* ── AI illustratie-generatie ─────────────────────────────────────────── */

/* "Genereer met AI"-keuzekaart: exact dezelfde upload-option-card-basis als
   Upload Afbeelding/Illustratie Editor (geen eigen kleur/gloed) — alleen het
   lint erboven onderscheidt 'm nog als aanbevolen. */
.illu-option-card { position: relative; overflow: visible; }
/* overflow:visible (nodig voor het lint hierboven) betekent dat de kaart het
   icoonvlak niet meer afknipt zoals bij de andere kaarten — geef het vlak
   daarom zelf ronde linkerhoeken, iets krapper dan de kaart (1rem) zodat 'ie
   netjes bínnen de kaartrand valt. */
.illu-option-card .upload-option-icon { border-radius: calc(1rem - 1px) 0 0 calc(1rem - 1px); }
.illu-ribbon {
    position: absolute;
    top: -0.65rem;
    right: 0.75rem;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    background: linear-gradient(135deg, #55a68a, #386f5b);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.2rem 0.65rem;
    border-radius: 50rem;
    box-shadow: 0 .2rem .5rem rgba(56, 111, 91, .35);
    z-index: 2;
}
.illu-ribbon i { font-size: .75rem; }

/* Modal-header: icoonbadge + titel + credits-chip. De header zelf wrapt NIET
   (anders belandt het kruisje — als het als enige naar een 2e regel valt —
   linksonder i.p.v. rechtsboven, want justify-content:space-between zet een
   enkel item op een lege regel gewoon aan het begin). Alleen de titel-groep
   zelf mag intern wrappen/krimpen; het kruisje blijft daardoor altijd op
   dezelfde regel, rechts uitgelijnd. */
.illu-modal-header { align-items: center; flex-wrap: nowrap; }
.illu-modal-title-group { display: flex; align-items: center; gap: .65rem; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
.illu-modal-header .btn-close { flex-shrink: 0; }
.illu-modal-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: linear-gradient(160deg, #55a68a, #386f5b);
    color: #fff;
    font-size: 1.1rem;
    flex-shrink: 0;
}
.illu-modal-title-group .modal-title { margin-bottom: 0; }
.illu-credits-chip {
    background: #f0f7f4;
    color: #386f5b;
    border: 1px solid rgba(68, 140, 116, .3);
    font-weight: 600;
    padding: .4rem .8rem;
}
/* Zelfde afmetingen als .illu-credits-chip hierboven, zodat de knop ernaast
   in de header niet kleiner (of groter) oogt dan de credits-pill. */
.illu-buy-credits-header-btn { padding: .4rem .8rem; font-size: .75rem; line-height: 1; }

/* Ruime bodem-padding i.p.v. de kleine 2.5rem: scrollModalToBottom() scrollt
   na elke stap naar de onderkant van de scrollhoogte, en zonder deze extra
   witruimte plakt de actuele stap dan tegen de onderrand van het scherm.
   Met deze marge erbij komt 'ie in plaats daarvan ongeveer in het midden
   van het beeld te staan. */
.illu-modal-body { padding: 1.75rem 2rem 20vh; }
.illu-section-inner { max-width: 900px; margin: 0 auto; }
.illu-hint { font-size: 0.85rem; color: #858c97; line-height: 1.5; }

/* Ruimte tussen stap 2/3 en de stap erboven: zonder dit las alles als één
   doorlopende tekst zodra een volgende stap verscheen. */
.illu-step-block { margin-top: 6rem; }

/* Genummerde stap-headers (1/2, of een icoon voor de latere stappen) */
.illu-step-title { display: flex; align-items: flex-start; gap: .85rem; margin-bottom: 1.75rem; }
.illu-step-title h5 { margin-bottom: .2rem; }
/* Paginabladerknoppen bij stap 3: rechts uitgelijnd naast de titel i.p.v. een
   eigen, gecentreerde regel eronder. */
.illu-step-title-nav { margin-left: auto; align-self: center; flex-shrink: 0; }
.illu-step-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: #f0f7f4;
    color: #386f5b;
    font-weight: 700;
    font-size: .95rem;
    flex-shrink: 0;
}
.illu-step-number i { font-size: 1rem; }

/* Stijlkeuze: grid i.p.v. flex, schaalt zelf mee naar minder kolommen op smalle schermen */
.illu-style-row {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 0.85rem;
}
.illu-style-btn {
    display: flex;
    flex-direction: column;
    border: 2px solid #e3e9ef;
    border-radius: 1rem;
    background: #fff;
    padding: .5rem;
    text-align: center;
    cursor: pointer;
    font-weight: 500;
    color: #576071;
    overflow: hidden;
    transition: border-color .15s ease, background-color .15s ease, transform .1s ease;
}
/* Per-stijl voorbeeldrenders (zelfde stilleven in elke stijl, gegenereerd
   met dezelfde stijlprompts als de boekillustraties) — zie
   STYLE_PREVIEW_IMAGES in ai_illustrations.js. */
.illu-style-preview {
    display: block;
    aspect-ratio: 1;
    border-radius: .6rem;
    background: #f6f9fc;
    margin-bottom: .6rem;
    overflow: hidden;
}
/* Volvlakse stijlrenders (geen padding/contain meer: dat was voor de oude
   sticker-plaatjes met witruimte eromheen). */
.illu-style-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.illu-style-label { display: flex; align-items: center; justify-content: center; gap: .4rem; }
.illu-style-label i { font-size: 1.1rem; color: #448c74; }
.illu-style-btn:hover { border-color: #a9cbbe; transform: translateY(-1px); }
.illu-style-btn.selected { border-color: #448c74; background: #f0f7f4; color: #2f4a3f; box-shadow: 0 .2rem .5rem rgba(68, 140, 116, .15); }

/* Afgeronde stappen vervagen zodat de focus op de huidige stap ligt; hover
   (of focus in een veld, voor toetsenbordgebruik) haalt de vervaging weg
   zodat de stap gewoon bruikbaar blijft. */
.illu-step-faded { opacity: .45; transition: opacity .2s ease; }
.illu-step-faded:hover,
.illu-step-faded:focus-within { opacity: 1; }

/* Zodra stap 2 in beeld komt heeft de stijlkeuze de aandacht niet meer nodig
   en wordt de rij ongeveer half zo hoog, zodat de volgende stap beter
   zichtbaar is. Alleen de hoogte krimpt: het grid (en dus de breedte van de
   knoppen) blijft hetzelfde, de vierkante preview wordt een liggend
   uitsnede-frame van vaste hoogte. */
.illu-style-row.compact .illu-style-btn { padding: .35rem .5rem; }
.illu-style-row.compact .illu-style-preview { aspect-ratio: auto; height: 3.75rem; margin-bottom: .35rem; }
/* object-position: top — de verkleinde (liggende) uitsnede knipt zo alleen
   de onderkant van het vierkante voorbeeld af i.p.v. boven én onder. */
.illu-style-row.compact .illu-style-preview img { object-position: top; }

/* Personage-cards (setup + sheets delen dezelfde basiskaart) */
.illu-char-card {
    border: 1px solid #e3e9ef;
    border-radius: 1rem;
    padding: 1.5rem;
    height: 100%;
    background: #fff;
    transition: box-shadow .15s ease, border-color .15s ease;
}
.illu-char-card:hover { border-color: #d3ddd8; box-shadow: 0 .2rem .6rem rgba(0, 0, 0, .05); }
.illu-char-card-header { display: flex; align-items: center; gap: .75rem; margin-bottom: 1.1rem; }
.illu-char-card-header h6 { margin-bottom: 0; font-size: 1.1rem; }
.illu-sheet-card h6 { font-size: 1.1rem; margin-bottom: .75rem; }
.illu-char-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    background: linear-gradient(160deg, #55a68a, #386f5b);
    color: #fff;
    font-weight: 700;
    font-size: 1.15rem;
    flex-shrink: 0;
}
.illu-type-switch { display: flex; gap: .5rem; margin-bottom: .9rem; }
.illu-type-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: .45rem .5rem;
    border: 1px solid #e3e9ef;
    border-radius: 2rem;
    background: #fff;
    color: #9099a6;
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;
}
.illu-type-btn:hover { border-color: #55a68a; color: #55a68a; }
.illu-type-btn.active { border-color: #55a68a; background: #55a68a; color: #fff; }
.illu-type-icon { display: inline-flex; font-size: 1rem; }
.illu-attr-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: .9rem 1rem; margin-bottom: .9rem; }
.illu-attr-field { display: block; margin-bottom: 0; }
/* Het extra-details-veld staat als laatste boven de opslaan-knop: zelfde
   ruimte eronder als de grid erboven heeft. */
.illu-attr-field-full { grid-column: 1 / -1; margin-bottom: .9rem; }
.illu-attr-label { display: block; font-size: .75rem; font-weight: 600; color: #9099a6; text-transform: uppercase; letter-spacing: .03em; margin-bottom: .3rem; }
.illu-cta-btn { padding: .65rem 1.75rem; font-size: 1rem; }

/* Character sheets: media-frame met status-overlay i.p.v. losse elementen eronder */
.illu-sheet-card { display: flex; flex-direction: column; }
.illu-sheet-media { position: relative; margin-bottom: 1rem; }
.illu-sheet-img { width: 100%; border-radius: 0.75rem; background: #f6f9fc; aspect-ratio: 1; object-fit: cover; display: block; }
.illu-sheet-spinner {
    width: 100%;
    aspect-ratio: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    background: #f6f9fc;
    border-radius: 0.75rem;
    color: #858c97;
    font-size: .85rem;
    padding: 1rem;
    text-align: center;
}
.illu-sheet-spinner .spinner-border { color: #448c74; }
.illu-sheet-spinner-error { color: #c0554b; background: #fdf3f2; }
.illu-sheet-approved-badge {
    position: absolute;
    top: .5rem;
    right: .5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    background: #3fca90;
    color: #fff;
    box-shadow: 0 .15rem .4rem rgba(0, 0, 0, .2);
}
.illu-sheet-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .5rem; margin-top: auto; }
.illu-approved-label { display: inline-flex; align-items: center; color: #2f9e6f; font-weight: 600; font-size: .85rem; }

/* Zodra alle personages goedgekeurd zijn (stap 3 komt in beeld) klappen de
   kaarten samen tot dit mini-rijtje — alleen nog een klein beeld, de naam en
   "goedgekeurd". Het potloodje opent alsnog de volledige kaart. Eén rij i.p.v.
   bootstraps standaard flex-wrap: past het niet, dan scrollt de rij
   horizontaal i.p.v. de kaartjes te verkleinen of naar een tweede regel te
   duwen. */
.illu-characters-row-mini { flex-wrap: nowrap; overflow-x: auto; margin: 0; gap: .6rem; padding-bottom: .25rem; }
.illu-char-mini {
    /* De kaartjes zijn geen bootstrap .col-*, maar .row > * forceert
       width:100% op ELK direct kind, col-class of niet — zonder deze
       override zou elk kaartje dus de volle breedte van de rij opeisen.
       (Gelijke specificiteit als .row > *, maar later in de cascade, dus dit
       wint sowieso — ook buiten .illu-characters-row-mini om, voor het geval
       er een personage bewerkt wordt en de rij dus terugvalt op gewoon
       wrappen i.p.v. de niet-wrappende mini-modus.) */
    width: auto;
    max-width: none;
    /* Staat een mini-kaartje op dezelfde flex-regel als een volle
       edit-kaart (bewerken van één personage terwijl de rest mini is), dan
       zou het anders meestrekken naar de hoogte van die veel hogere kaart. */
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    flex-shrink: 0;
    border: 1px solid #e3e9ef;
    border-radius: 50rem;
    padding: .35rem .9rem .35rem .35rem;
    background: #fff;
}
.illu-char-mini-img { width: 2.25rem; height: 2.25rem; border-radius: 50%; object-fit: cover; flex-shrink: 0; background: #f6f9fc; }
.illu-char-mini-name { font-weight: 600; font-size: .9rem; }
.illu-char-mini-badge { display: inline-flex; align-items: center; color: #2f9e6f; font-size: .95rem; }
.illu-char-mini-edit { border: none; background: none; color: #9099a6; padding: .2rem; line-height: 1; cursor: pointer; }
.illu-char-mini-edit:hover { color: #448c74; }

/* Stap 3: pagina-wisselaar — zelfde opzet als #book_direction_btn_group bij
   het boek zelf, maar met een eigen index los van waar het boek op staat. */
#ai_page_nav .btn { width: 2.75rem; }
#ai_page_indicator { cursor: default; pointer-events: none; width: 2.75rem; }

/* Stap 3: scène-context, gepersonaliseerd van de generieke bg-secondary card */
.illu-scene-card {
    background: #f6fbf9;
    border: 1px solid #e3e9ef;
    border-left: 3px solid #448c74;
    border-radius: .75rem;
    padding: .85rem 1rem;
    margin-bottom: 1.75rem;
}

/* Iets meer lucht tussen de onderdelen binnen de stappen van de AI-modal:
   de labels boven de blokken in stap 3 en de acties onder de kaarten in
   stap 2 stonden er strak tegenaan, waardoor het geheel druk oogde. */
#ai_generate_section .settings-label { margin-top: .5rem; margin-bottom: .5rem; }
#ai_characters_row { margin-bottom: .75rem; }
#ai_setup_submit { margin-top: .5rem; }

/* Onopvallende onthul-knop voor de personage-keuze: leest als een tekstlink,
   niet als actieknop — de meeste gebruikers hoeven hier niets te kiezen.
   Bovenaan uitgelijnd (op dezelfde hoogte als het "Extra aanwijzingen"-label
   ernaast) en rechts in de kolom. */
.illu-reveal-characters {
    display: block;
    margin: 0.5rem 0 0 auto;
    padding: 0;
    border: 0;
    background: none;
    font-size: .85rem;
    color: #858c97;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}
.illu-reveal-characters:hover { color: #448c74; }
.illu-reveal-characters i { text-decoration: none; }
/* Mini-sluitknopje naast "Wie staan er op deze pagina?": klapt de keuze weer
   in en geeft de regie terug aan het model (characters_explicit -> false). */
.illu-close-characters {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    margin-left: .35rem;
    padding: 0;
    border: 1px solid #d7dde2;
    border-radius: 50%;
    background: #fff;
    color: #858c97;
    font-size: .55rem;
    line-height: 1;
    cursor: pointer;
    vertical-align: text-bottom;
    transition: color .15s ease, border-color .15s ease;
}
.illu-close-characters:hover { color: #448c74; border-color: #a9cbbe; }

/* Personage-chips om te selecteren wie er op de pagina staat */
.illu-char-check {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    border: 1px solid #e3e9ef;
    border-radius: 50rem;
    padding: 0.3rem 0.9rem 0.3rem 0.3rem;
    margin: 0 0.4rem 0.4rem 0;
    cursor: pointer;
    font-weight: 500;
    transition: border-color .15s ease, background-color .15s ease;
}
.illu-char-check:hover { border-color: #a9cbbe; }
.illu-char-check.checked { border-color: #448c74; background: #f0f7f4; color: #2f4a3f; }
.illu-char-check img { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; }

.illu-running-info {
    display: flex;
    align-items: center;
    gap: .75rem;
    background: #f0f7f4;
    border: 1px solid rgba(68, 140, 116, .25);
    color: #2f4a3f;
    border-radius: .75rem;
    padding: .85rem 1rem;
    font-size: .9rem;
    line-height: 1.5;
}
.illu-running-info .spinner-border { color: #448c74; flex-shrink: 0; }

.illu-buy-box {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    background: #fff;
    border: 1px solid rgba(68, 140, 116, .3);
    border-radius: 1rem;
    padding: 1.1rem 1.25rem;
    box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
.illu-buy-box-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    background: #f0f7f4;
    color: #448c74;
    font-size: 1.2rem;
    flex-shrink: 0;
}
.illu-buy-box-body { flex: 1 1 auto; min-width: 0; }

/* ── Credits-popup ("Genereer voor alle pagina's" met te weinig credits) ──
   Compacte conversie-popup: gradient-icoon, voortgangsbalkje dat toont hoe
   ver je credits reiken, en een uitgelicht aanbod-kader met badge. */
.illu-credits-popup {
    border: 0;
    border-radius: 1.25rem;
    padding: 2.25rem 1.75rem 1.5rem;
    text-align: center;
    box-shadow: 0 1rem 3rem rgba(18, 21, 25, .18);
}
.illu-credits-popup-close { position: absolute; top: 1rem; right: 1rem; z-index: 1; }
.illu-credits-popup-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    background: linear-gradient(160deg, #55a68a, #386f5b);
    color: #fff;
    font-size: 1.5rem;
    margin: 0 auto 1rem;
    box-shadow: 0 .35rem .9rem rgba(56, 111, 91, .35);
}
.illu-credits-popup-title { color: #2f4a3f; font-weight: 700; margin-bottom: .4rem; }
/* nowrap: de zin moet op één regel blijven (dialog is daarvoor verbreed naar
   35rem); op smalle schermen laten we 'm wél gewoon wrappen i.p.v. overlopen. */
.illu-credits-popup-sub { color: #576071; font-size: .95rem; margin-bottom: 1rem; white-space: nowrap; }
@media (max-width: 575.98px) {
    .illu-credits-popup-sub { white-space: normal; }
}
.illu-credits-progress {
    height: 8px;
    max-width: 15rem;
    margin: 0 auto 1.75rem;
    background: #edf1f5;
    border-radius: 4px;
    overflow: hidden;
}
.illu-credits-progress-fill {
    height: 100%;
    width: 0;
    background: linear-gradient(90deg, #55a68a, #386f5b);
    border-radius: 4px;
    transition: width .5s ease;
}
.illu-credits-offer {
    position: relative;
    background: #f0f7f4;
    border: 1px solid rgba(68, 140, 116, .3);
    border-radius: 1rem;
    padding: 1.4rem 1.25rem .9rem;
    margin-bottom: 1.25rem;
}
.illu-credits-offer-badge {
    position: absolute;
    top: -.75rem;
    left: 50%;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    white-space: nowrap;
    background: linear-gradient(135deg, #55a68a, #386f5b);
    color: #fff;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    padding: .25rem .7rem;
    border-radius: 50rem;
    box-shadow: 0 .2rem .5rem rgba(56, 111, 91, .35);
}
.illu-credits-offer-amount { font-size: 1.2rem; font-weight: 700; color: #2f4a3f; margin-bottom: .35rem; }
.illu-credits-offer-price { font-weight: 600; color: #448c74; }
.illu-credits-offer p { font-size: .85rem; color: #6b7f77; line-height: 1.55; margin: 0; }
.illu-credits-popup-later {
    display: block;
    margin: .35rem auto 0;
    border: 0;
    background: none;
    color: #858c97;
    font-size: .9rem;
}
.illu-credits-popup-later:hover { color: #576071; }

/* Waarschuwing bij het bewerken van stijl/personages (setup-stap): iets
   wordt opnieuw gegenereerd en dat kan credits kosten. */
.illu-setup-warning {
    background: #fdf6ec;
    border: 1px solid #f0d9a8;
    color: #7a5b1e;
    border-radius: .75rem;
    padding: .9rem 1rem;
}
.illu-setup-warning i { color: #d9a441; }

/* ── Mobiel (de mobile_warning_modal is te sluiten, dus dit blijft nodig) ── */
@media (max-width: 767.98px) {
    .illu-modal-body { padding: 1.25rem 1rem 2rem; }
    .illu-modal-title-group .modal-title { font-size: 1.05rem; }
    .illu-style-row { grid-template-columns: repeat(3, 1fr); gap: .5rem; }
    .illu-style-btn { padding: .75rem .35rem; font-size: .8rem; }
    .illu-attr-grid { grid-template-columns: 1fr; }
    .illu-char-card { padding: .9rem; }
    .illu-cta-btn, #ai_buy_btn { width: 100%; }
    .illu-buy-box { flex-direction: column; align-items: stretch; text-align: center; }
    .illu-buy-box-icon { margin: 0 auto; }
    .illu-sheet-actions { flex-direction: column; align-items: stretch; }
    .illu-sheet-actions .btn { width: 100%; }
}

@media (max-width: 420px) {
    .illu-style-row { grid-template-columns: repeat(2, 1fr); }
}
