/* =====================================================================
   Ulalu — appareil photo jetable numérique, page invité (D-079)
   ---------------------------------------------------------------------
   Chargée par la page invité quand l'appareil est actif, après guest.css.
   Trois ensembles : la carte de l'appareil dans la page (.cam-card), le
   viseur plein écran (.cam), la pellicule révélée et sa vue agrandie
   (.roll, .roll-view).

   Le viseur est sombre quel que soit le thème : c'est un boîtier, pas une
   page. La carte et la pellicule suivent les jetons du système de design,
   donc le mode sombre sans règle en plus.

   Pensé pour 375 px de large : cibles de 44 px au moins, déclencheur sous
   le pouce, zones sûres des téléphones à encoche respectées.

   Sommaire : 1 carte · 2 viseur · 3 déclencheur et commandes · 4 éclair
   · 5 pellicule révélée · 6 vue agrandie · 7 mouvement
   ===================================================================== */

/* ---------- 1. Carte de l'appareil ---------- */
.cam-card { margin: 0; display: grid; gap: .55rem; }

.cam-card__head { display: flex; align-items: center; gap: .9rem; }
.cam-card__title { font-size: var(--t-xl); margin: 0 0 .15rem; }
.cam-card__hint { margin: 0; font-size: var(--t-sm); line-height: 1.45; }

.cam-card__art {
    flex: 0 0 auto;
    width: 4.4rem;
    height: 3.1rem;
    display: grid;
    place-items: center;
}
.cam-card__art svg { width: 100%; height: 100%; display: block; overflow: visible; }
.cam-art__body { fill: #25202b; }
.cam-art__band { fill: var(--ember); }
.cam-art__flash { fill: #efe7dc; stroke: #25202b; stroke-width: 1.5; }
.cam-art__ring { fill: #3a3342; stroke: #0f0c12; stroke-width: 1.5; }
.cam-art__lens { fill: #0c0a0f; stroke: #6a6075; stroke-width: 1; }
.cam-art__finder { fill: #0c0a0f; stroke: #6a6075; stroke-width: 1; }
.cam-art__button { fill: var(--amber); }

/* Le compteur de poses : une fenêtre de boîtier, chiffres orangés sur fond noir. */
.cam-card__meter { display: flex; align-items: center; gap: .65rem; margin-top: .35rem; }
.cam-card__meter-label { font-size: var(--t-sm); color: var(--ink-2); font-weight: 550; }

.cam-digits {
    display: inline-block;
    min-width: 2.6ch;
    padding: .18rem .45rem .12rem;
    border-radius: 8px;
    background: #141016;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, .7), 0 0 0 2px #2f2934;
    color: #ffb347;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: .06em;
    text-align: center;
    font-variant-numeric: tabular-nums;
    text-shadow: 0 0 10px rgba(255, 150, 60, .45);
}

.cam-card__reveal { margin: 0; font-size: var(--t-sm); color: var(--ink-2); }

.cam-card label { margin-top: .35rem; }
.cam-card input[type=text] { scroll-margin-bottom: 6rem; }
.cam-card .field-help { margin: 0; }

.cam-card__open { min-height: 56px; margin-top: .45rem; }
.cam-card__open-dot {
    width: .7rem;
    height: .7rem;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .35);
}

.cam-card__status { margin: 0; min-height: 1.3em; font-size: var(--t-sm); color: var(--ink-2); }
.cam-card__status:empty { min-height: 0; }

.cam-card__developing,
.cam__developing {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0;
    font-size: var(--t-xs);
    letter-spacing: .02em;
}
.cam-card__developing { color: var(--muted-ink); }

/* « En développement » : une petite lampe de chambre noire. */
.cam-dot {
    flex: 0 0 auto;
    width: .55rem;
    height: .55rem;
    border-radius: 50%;
    background: #d9412b;
    box-shadow: 0 0 8px rgba(217, 65, 43, .7);
    animation: cam-glow 2.4s ease-in-out infinite;
}

/* Toutes les pellicules du palier sont distribuées (D-088) : la carte le dit, sans compteur, prénom ni déclencheur. */
.cam-card__full {
    display: grid;
    gap: .3rem;
    padding: .8rem .95rem;
    border-radius: var(--r);
    border: 1px solid color-mix(in srgb, var(--amber) 55%, var(--line));
    background: color-mix(in srgb, var(--amber) 9%, var(--surface));
    font-size: var(--t-sm);
    line-height: 1.45;
}
.cam-card__full p { margin: 0; }
.cam-card__full-title { font-size: var(--t-md); font-weight: 650; color: var(--ink); }
.cam-card.is-full :is(.cam-card__hint, .cam-card__meter, [data-slot="signature"], .cam-card__open, .cam-card__fallback) {
    display: none !important;
}

/* Pellicule finie et tout parti : la carte « Vos photos sont envoyées » prend la place de l'appareil, elle ne s'ajoute
   pas dessous. C'était l'intention depuis le début ; sans cette règle, les deux restaient à l'écran (2026-09-21). */
.cam-card.is-sent { display: none; }

.cam-card__fallback { display: grid; gap: .5rem; margin-top: .2rem; }
.cam-card__fallback p { margin: 0; font-size: var(--t-sm); }
.cam-card__fallback label.button { margin: 0; min-height: 52px; }
/* D-107 : l'appareil du téléphone en dernier recours, un lien discret sous « Réessayer ». */
.cam-card__phone { display: grid; gap: .15rem; margin-top: .3rem; }
.cam-card__phone-link { justify-self: start; margin: 0; font-size: var(--t-sm); color: var(--ink-2); text-decoration: underline; text-underline-offset: .2em; cursor: pointer; }

/* Le champ fichier reste atteignable au clavier : masqué à l'œil seulement. */
.cam-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    margin: 0;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
}
.cam-input:focus-visible + label { box-shadow: var(--focus); outline: 2px solid var(--ember); outline-offset: 2px; }
.cam-input:disabled + label { opacity: .5; pointer-events: none; }

.cam-wait { margin: 0; text-align: center; }
.cam-wait .eyebrow { justify-content: center; }

/* ---------- 2. Viseur ---------- */
html.cam-open, html.cam-open body { overflow: hidden; }

.cam {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto auto;
    gap: .7rem;
    padding: max(.7rem, env(safe-area-inset-top)) max(.8rem, env(safe-area-inset-right)) max(.9rem, env(safe-area-inset-bottom)) max(.8rem, env(safe-area-inset-left));
    color: #f4efe8;
    background:
        radial-gradient(120% 80% at 50% 0%, #2a2430 0%, #141117 55%, #0b090d 100%);
    color-scheme: dark;
    -webkit-user-select: none;
    user-select: none;
    touch-action: manipulation;
}
.cam[hidden] { display: none !important; }

.cam__top { display: flex; align-items: center; justify-content: space-between; gap: .6rem; }

.cam__brand {
    font-family: var(--font-display);
    font-size: .95rem;
    font-weight: 650;
    letter-spacing: .28em;
    text-transform: uppercase;
    color: rgba(244, 239, 232, .55);
}

.cam__counter .cam-digits { font-size: 1.35rem; }

.cam__finder {
    position: relative;
    min-height: 0;
    border-radius: 22px;
    overflow: hidden;
    background: #050406;
    box-shadow: 0 0 0 3px #1c1820, 0 0 0 5px #0a080c, inset 0 0 40px rgba(0, 0, 0, .8);
}

.cam__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: #050406;
}

/* Le cadre du viseur : quatre équerres et un assombrissement des bords, comme dans l'œilleton d'un jetable. */
.cam__frame {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        linear-gradient(#fff, #fff) left 16px top 16px / 26px 2px no-repeat,
        linear-gradient(#fff, #fff) left 16px top 16px / 2px 26px no-repeat,
        linear-gradient(#fff, #fff) right 16px top 16px / 26px 2px no-repeat,
        linear-gradient(#fff, #fff) right 16px top 16px / 2px 26px no-repeat,
        linear-gradient(#fff, #fff) left 16px bottom 16px / 26px 2px no-repeat,
        linear-gradient(#fff, #fff) left 16px bottom 16px / 2px 26px no-repeat,
        linear-gradient(#fff, #fff) right 16px bottom 16px / 26px 2px no-repeat,
        linear-gradient(#fff, #fff) right 16px bottom 16px / 2px 26px no-repeat,
        radial-gradient(ellipse at center, transparent 58%, rgba(0, 0, 0, .45) 100%);
    opacity: .85;
}

.cam__notice {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: min(88%, 22rem);
    margin: 0;
    padding: .8rem 1rem;
    border-radius: 14px;
    background: rgba(10, 8, 12, .78);
    color: #f4efe8;
    font-size: var(--t-md);
    line-height: 1.4;
    text-align: center;
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}
.cam.is-done .cam__video { filter: brightness(.35) saturate(.4); }

/* ---------- 3. Déclencheur et commandes ---------- */
.cam__bottom {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    justify-items: center;
    padding-inline: .4rem;
}
.cam__bottom > :first-child { justify-self: start; }
.cam__bottom > :last-child { justify-self: end; }

.cam__icon {
    width: 48px;
    height: 48px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, .16);
    border-radius: 50%;
    background: rgba(255, 255, 255, .08);
    color: #f4efe8;
    cursor: pointer;
    transition: background .18s, color .18s, transform .12s;
}
.cam__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cam__icon:hover { background: rgba(255, 255, 255, .16); }
.cam__icon:active { transform: scale(.94); }
.cam__icon:focus-visible { outline: 2px solid #ffb347; outline-offset: 3px; }
/* Grid slots keep their place when a button is hidden. */
.cam__bottom .cam__icon[hidden] { display: grid !important; visibility: hidden; }
#camera-flash.is-on { background: #ffb347; border-color: #ffb347; color: #1a1420; }
#camera-flash.is-on svg { fill: currentColor; }

.cam__shutter {
    position: relative;
    width: 84px;
    height: 84px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    box-shadow: 0 0 0 4px #f4efe8, 0 6px 22px rgba(0, 0, 0, .55);
    cursor: pointer;
    transition: transform .12s cubic-bezier(.2, .8, .2, 1), box-shadow .2s, opacity .2s;
}
.cam__shutter-core {
    position: absolute;
    inset: 8px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #ff8a5c, var(--ember) 55%, #b8361c);
    box-shadow: inset 0 -3px 6px rgba(0, 0, 0, .35), inset 0 2px 4px rgba(255, 255, 255, .25);
}
.cam__shutter:active:not([disabled]) { transform: scale(.9); }
.cam__shutter:focus-visible { outline: none; box-shadow: 0 0 0 4px #f4efe8, 0 0 0 8px #ffb347; }
.cam__shutter[disabled] { opacity: .45; cursor: default; transform: none; }

.cam__developing { justify-content: center; min-height: 1.2em; color: rgba(244, 239, 232, .7); }
.cam__developing:has(#camera-viewer-developing:empty) .cam-dot { display: none; }

/* Écrans bas (téléphone à l'horizontale) : le déclencheur passe à droite du viseur. */
@media (orientation: landscape) and (max-height: 32rem) {
    .cam {
        grid-template-columns: minmax(0, 1fr) auto;
        grid-template-rows: auto minmax(0, 1fr) auto;
        gap: .5rem .9rem;
    }
    .cam__top { grid-column: 1 / -1; }
    .cam__finder { grid-row: 2 / 4; }
    .cam__bottom { grid-column: 2; grid-row: 2; grid-template-columns: auto; grid-template-rows: 1fr auto 1fr; gap: .6rem; }
    .cam__bottom > :first-child, .cam__bottom > :last-child { justify-self: center; }
    .cam__developing { grid-column: 2; grid-row: 3; }
}

/* ---------- 4. Éclair ---------- */
.cam__flashfx {
    position: fixed;
    inset: 0;
    background: #fff;
    opacity: 0;
    pointer-events: none;
    z-index: 2;
}
.cam__flashfx.is-firing { animation: cam-flash .24s ease-out; }

/* ---------- 5. Pellicule révélée ---------- */
.roll { margin: 0; }
.roll h2 { font-size: var(--t-xl); margin-bottom: .2rem; }
.roll__count { margin: 0 0 .9rem; }

/* Chaque photo est un tirage : un bord clair, une ombre, comme posé sur la table. */
.roll__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(6.4rem, 1fr));
    gap: .6rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.roll__shot {
    position: relative;
    display: block;
    width: 100%;
    padding: 4px 4px 4px;
    border: 0;
    border-radius: 4px;
    background: #fbf8f2;
    box-shadow: 0 1px 2px rgba(40, 20, 10, .18), 0 6px 14px rgba(40, 20, 10, .12);
    cursor: zoom-in;
    transition: transform .18s cubic-bezier(.2, .8, .2, 1), box-shadow .18s;
}
.roll__shot img {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    border-radius: 2px;
    background: #d9d1c5;
}
.roll__shot:hover { transform: translateY(-2px) rotate(-.4deg); box-shadow: 0 2px 4px rgba(40, 20, 10, .2), 0 12px 24px rgba(40, 20, 10, .16); }
.roll__shot:focus-visible { outline: 2px solid var(--ember); outline-offset: 3px; }

.roll__by {
    position: absolute;
    left: 4px;
    right: 4px;
    bottom: 4px;
    padding: 1rem .35rem .25rem;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(transparent, rgba(0, 0, 0, .55));
    color: #fff;
    font-size: .72rem;
    line-height: 1.2;
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.roll__more { margin: .9rem 0 .6rem; text-align: center; }
.roll__more .button { min-height: 44px; }

@media (min-width: 40rem) {
    .roll__grid { grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); gap: .8rem; }
}

/* ---------- 6. Vue agrandie ---------- */
html.roll-open { overflow: hidden; }

.roll-view {
    width: 100vw;
    max-width: 100vw;
    /* vh d'abord, dvh ensuite : un navigateur qui ignore dvh garde la ligne d'avant. Sans ce repli, ni hauteur ni
       plafond ne s'appliquaient, la photo reprenait sa taille et la barre des boutons tombait au milieu d'elle. */
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    margin: 0;
    padding: 0;
    border: 0;
    background: #0b090d;
    color: #f4efe8;
    color-scheme: dark;
}
/* Posé ici, et non laissé au navigateur : camera-roll.js retombe sur l'attribut « open » quand showModal manque, et un
   dialogue ouvert ainsi reste dans le flux de la page — sans surimpression, la photo débordait l'écran (2026-09-21). */
.roll-view[open] {
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto;
    position: fixed;
    /* Les quatre côtés écrits un par un : le navigateur qui n'a pas de <dialog> n'a pas « inset » non plus. */
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    inset: 0;
    z-index: 60;
    padding-top: env(safe-area-inset-top, 0px);
}
.roll-view::backdrop { background: rgba(8, 6, 10, .92); }

.roll-view__stage {
    position: relative;   /* repère de la photo, posée juste en dessous */
    min-height: 0;
    padding: 0;
}
/* La photo est posée en absolu dans la scène, et non simplement plafonnée à 100 % : la hauteur de la scène est décidée
   par la grille, et un maximum en pourcentage ne s'y résout pas — seule la largeur limitait. D'où une photo qui tenait
   sur un téléphone (portrait, écran étroit) et débordait sur un grand écran, la légende et les boutons par-dessus elle
   (2026-09-21). Les quatre côtés posés et les marges automatiques, le pourcentage se résout et la photo se centre. */
.roll-view__img {
    position: absolute;
    top: .8rem;
    right: .8rem;
    bottom: .4rem;
    left: .8rem;
    margin: auto;
    width: auto;
    height: auto;
    max-width: calc(100% - 1.6rem);
    max-height: calc(100% - 1.2rem);
    object-fit: contain;
    border: 6px solid #fbf8f2;
    border-radius: 3px;
    box-shadow: 0 18px 50px rgba(0, 0, 0, .6);
    background: #1a161d;
}

.roll-view__bar {
    display: grid;
    gap: .5rem;
    padding: .4rem .8rem max(.9rem, env(safe-area-inset-bottom));
}
.roll-view__caption { margin: 0; min-height: 1.3em; text-align: center; font-size: var(--t-sm); color: rgba(244, 239, 232, .85); }

.roll-view__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .5rem;
}
.roll-view__actions .button { min-height: 44px; }
.roll-view__close { --btn-bg: transparent; --btn-fg: #f4efe8; --btn-line: rgba(255, 255, 255, .3); }

.roll-view__nav {
    width: 48px;
    height: 48px;
    padding: 0;
    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 50%;
    background: rgba(255, 255, 255, .08);
    color: #f4efe8;
    font-size: 1.8rem;
    line-height: 1;
    cursor: pointer;
}
.roll-view__nav:hover { background: rgba(255, 255, 255, .16); }
.roll-view__nav:focus-visible { outline: 2px solid #ffb347; outline-offset: 3px; }

/* ---------- 7. Mouvement ---------- */
@keyframes cam-flash {
    0% { opacity: .95; }
    100% { opacity: 0; }
}

@keyframes cam-glow {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
    .cam-dot { animation: none; }
    /* L'éclair reste, plus doux : c'est le seul signe que la photo est prise. */
    .cam__flashfx.is-firing { animation-duration: .16s; }
    @keyframes cam-flash { 0% { opacity: .5; } 100% { opacity: 0; } }
    .roll__shot, .cam__shutter, .cam__icon { transition: none; }
    .roll__shot:hover { transform: none; }
}
