/* ═══════════════════════════════════════════════════════════════════════
   Guest templates — shared base
   ───────────────────────────────────────────────────────────────────────
   Loaded before every per-template stylesheet (public/css/guest/<key>.css).

   Holds only what is genuinely universal across all seven templates:
   page resets, the gallery tile internals, the secondary-page skeleton
   (password / rsvp / find-table / invite) and the alert banners.

   Everything visual — palette, type, geometry, chrome — belongs in the
   template's own file, which restyles these same class names. That is why
   the secondary pages don't need seven copies of themselves: they're built
   from .gt-shell / .gt-card / .gt-input / .gt-btn, and each template makes
   those look like it.

   Owner theme colors arrive as custom properties from
   guest::partials.head, and only the ones a template declares in
   config/guest-templates.php are emitted. Always read them with a fallback
   — var(--ev-accent, #333) — so a template that doesn't take a given color
   still renders its own designed value.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Page resets ─────────────────────────────────────────────────────── */
html { -webkit-tap-highlight-color: transparent; }
.gt-body { margin: 0; min-height: 100vh; -webkit-font-smoothing: antialiased; }
.gt-no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.gt-no-scrollbar::-webkit-scrollbar { display: none; }
.gt-safe-bottom { padding-bottom: env(safe-area-inset-bottom); }

.gt-press { transition: transform .12s ease, opacity .12s ease; }
.gt-press:active { transform: scale(.97); opacity: .9; }

.gt-hidden { display: none !important; }

/* Visible keyboard focus on every template. */
.gt-body :focus-visible {
    outline: 2px solid var(--ev-accent, #2563eb);
    outline-offset: 2px;
}

/* Touch devices can't hover: show tile overlays by default and only
   hide-until-hover where hover actually exists. */
.gt-reveal { opacity: 1; }
@media (hover: hover) {
    .gt-reveal { opacity: 0; transition: opacity .18s ease; }
    .gt-tile:hover .gt-reveal, .gt-tile:focus-within .gt-reveal { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .gt-body *, .gt-body *::before, .gt-body *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}

/* ── Gallery tile ────────────────────────────────────────────────────── */
/* Geometry (aspect ratio, grid spans, radius) is set per template; the
   internals below are shared, including by the items appended over AJAX by
   guest-event.js — so every template gets working infinite scroll for free. */
.gt-tile {
    position: relative;
    overflow: hidden;
    background: rgba(128, 128, 128, .12);
}
.gt-tile__link { display: block; width: 100%; height: 100%; }
.gt-tile__img {
    display: block; width: 100%; height: 100%;
    object-fit: cover;
    transition: transform .35s ease;
}
@media (hover: hover) {
    .gt-tile:hover .gt-tile__img { transform: scale(1.06); }
}
.gt-tile--video .gt-tile__link { background: #101012; }
.gt-tile__play {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    pointer-events: none;
}
.gt-tile__play span {
    display: grid; place-items: center;
    width: 2.75rem; height: 2.75rem; border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, .7);
    background: rgba(0, 0, 0, .3);
    backdrop-filter: blur(4px);
    color: #fff; font-size: 1.05rem;
    transition: transform .3s ease;
}
@media (hover: hover) { .gt-tile:hover .gt-tile__play span { transform: scale(1.1); } }
.gt-tile__badge {
    position: absolute; top: .375rem; right: .375rem;
    color: #fff; font-size: .75rem;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6));
    pointer-events: none;
}
.gt-tile__act {
    position: absolute; z-index: 2;
    width: 1.75rem; height: 1.75rem; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0, 0, 0, .55); color: #fff;
    font-size: .7rem; border: 0; cursor: pointer;
    transition: background .15s ease;
}
.gt-tile__act--download { bottom: .375rem; right: .375rem; }
.gt-tile__act--download:hover { background: rgba(0, 0, 0, .82); }
.gt-tile__act--delete { top: .375rem; left: .375rem; }
.gt-tile__act--delete:hover { background: #ef4444; }
.gt-tile__form { position: absolute; top: .375rem; left: .375rem; z-index: 2; margin: 0; }
.gt-tile__form .gt-tile__act { position: static; }
.gt-tile__cap {
    position: absolute; inset: auto 0 0 0;
    padding: .375rem;
    background: linear-gradient(to top, rgba(0, 0, 0, .62), transparent);
    color: #fff; font-size: .625rem; line-height: 1.3;
    pointer-events: none;
}
.gt-tile__cap b { display: block; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gt-tile__cap span { opacity: .75; }

/* Infinite-scroll sentinel */
.gt-sentinel {
    display: flex; align-items: center; justify-content: center; gap: .5rem;
    padding: 2rem 0; font-size: .875rem; opacity: .6;
}

/* ── Empty states ────────────────────────────────────────────────────── */
.gt-empty { text-align: center; padding: 3rem 1rem; font-size: .875rem; opacity: .6; }

/* ── Alert banners ───────────────────────────────────────────────────── */
.gt-alerts { display: grid; gap: .5rem; padding: 1rem 1rem 0; }
.gt-alert {
    padding: .75rem;
    border: 1px solid;
    border-radius: .75rem;
    font-size: .875rem;
    line-height: 1.45;
}
.gt-alert--ok    { background: #ecfdf5; border-color: #a7f3d0; color: #047857; }
.gt-alert--error { background: #fef2f2; border-color: #fecaca; color: #b91c1c; }
.gt-alert--warn  { background: #fffbeb; border-color: #fde68a; color: #b45309; }
.gt-alert--info  { background: #eff6ff; border-color: #bfdbfe; color: #1d4ed8; }

/* ═══════════════════════════════════════════════════════════════════════
   Secondary pages — password gate, RSVP, find-my-table, invitation
   ───────────────────────────────────────────────────────────────────────
   One skeleton, restyled per template. Keeps four guest-facing pages in
   step with whichever template the event is on without maintaining
   4 × 7 = 28 view files.
   ═══════════════════════════════════════════════════════════════════════ */
.gt-shell {
    min-height: 100vh;
    display: flex; align-items: center; justify-content: center;
    padding: 1.5rem 1rem;
}
.gt-shell--top { align-items: flex-start; padding-top: 2.5rem; }

.gt-card {
    width: 100%; max-width: 26rem;
    background: #fff; color: #1f2937;
    border-radius: 1rem;
    padding: 1.75rem 1.5rem;
    box-shadow: 0 20px 45px -22px rgba(0, 0, 0, .45);
}
.gt-card--wide { max-width: 34rem; }

.gt-card__icon {
    width: 3.25rem; height: 3.25rem; border-radius: 1rem;
    display: grid; place-items: center; margin: 0 auto 1rem;
    background: var(--ev-accent, #317265); color: var(--ev-accent-text, #fff);
    font-size: 1.15rem;
}
.gt-card__kick {
    font-size: .65rem; text-align: center; margin: 0 0 .35rem;
    letter-spacing: .2em; text-transform: uppercase; opacity: .55;
}
.gt-card__title { font-size: 1.2rem; font-weight: 700; text-align: center; margin: 0 0 .25rem; line-height: 1.25; }
.gt-card__sub { font-size: .8rem; text-align: center; opacity: .6; margin: 0 0 1.25rem; }
.gt-card__lede { font-size: .85rem; text-align: center; opacity: .75; margin: 0 0 1.25rem; }
.gt-card__foot { margin-top: 1.25rem; text-align: center; font-size: .8rem; }
.gt-card__foot a { color: var(--ev-accent, #317265); text-decoration: none; }
.gt-card__foot a:hover { text-decoration: underline; }

.gt-form { display: grid; gap: .75rem; }
.gt-field { display: grid; gap: .3rem; }
.gt-label { font-size: .8rem; font-weight: 600; }
.gt-hint { font-size: .7rem; opacity: .55; }
.gt-input,
.gt-select,
.gt-textarea {
    width: 100%;
    padding: .65rem .9rem;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: .75rem;
    font: inherit; font-size: .875rem;
    color: inherit;
}
.gt-textarea { resize: vertical; min-height: 6rem; }
.gt-input:focus, .gt-select:focus, .gt-textarea:focus {
    outline: none;
    border-color: var(--ev-accent, #317265);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--ev-accent, #317265) 22%, transparent);
}

.gt-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
    width: 100%; padding: .75rem 1.25rem;
    background: var(--ev-accent, #317265); color: var(--ev-accent-text, #fff);
    border: 0; border-radius: .75rem;
    font: inherit; font-size: .875rem; font-weight: 600;
    cursor: pointer; text-decoration: none;
    transition: filter .15s ease, transform .12s ease;
}
.gt-btn:hover { filter: brightness(.94); }
.gt-btn:active { transform: scale(.985); }
.gt-btn--ghost {
    background: transparent; color: inherit;
    border: 1px solid #e5e7eb;
}
.gt-btn--ghost:hover { background: rgba(0, 0, 0, .04); filter: none; }

.gt-input--sm { width: 7rem; }

/* Radio group used by the RSVP / invitation status picker. The input is
   visually hidden and the <span> is the control, so the checked state can be
   styled without :has() support — :checked + span is enough. */
.gt-choices { display: grid; gap: .5rem; }
.gt-choices--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.gt-choice { cursor: pointer; }
.gt-choice input {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.gt-choice > span {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .3rem;
    padding: .7rem .5rem; min-height: 100%;
    border: 1px solid #e5e7eb; border-radius: .75rem;
    font-size: .75rem; font-weight: 500; text-align: center;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.gt-choice:hover > span { background: rgba(0, 0, 0, .025); }
.gt-choice input:checked + span {
    border-color: var(--ev-accent, #317265);
    background: color-mix(in srgb, var(--ev-accent, #317265) 10%, transparent);
    color: var(--ev-accent, #317265);
}
.gt-choice input:focus-visible + span {
    outline: 2px solid var(--ev-accent, #317265); outline-offset: 2px;
}

/* Seat callout — the invitation's "your table" line and the find-my-table hit. */
.gt-seat {
    padding: .85rem 1rem; margin-bottom: 1rem;
    border: 1px solid color-mix(in srgb, var(--ev-accent, #317265) 30%, transparent);
    background: color-mix(in srgb, var(--ev-accent, #317265) 9%, transparent);
    border-radius: .75rem; text-align: center; font-size: .875rem;
}
.gt-seat--big { padding: 1.25rem 1rem; }
.gt-seat__who { margin: 0; font-size: .8rem; opacity: .6; }
.gt-seat__table { margin: .25rem 0 0; font-size: 1.6rem; font-weight: 700; line-height: 1.1; }
.gt-seat__note { margin: .35rem 0 0; font-size: .75rem; opacity: .6; }

.gt-matches { display: grid; gap: .5rem; margin-top: 1rem; }
.gt-match {
    display: flex; align-items: center; justify-content: space-between; gap: .75rem;
    padding: .8rem .9rem;
    border: 1px solid #e5e7eb; border-radius: .75rem;
}
.gt-match b { font-size: .9rem; }
.gt-match span {
    font-size: .8rem; font-weight: 700;
    padding: .2rem .6rem; border-radius: 2rem;
    background: var(--ev-accent, #317265); color: var(--ev-accent-text, #fff);
}

/* ─── Section images ────────────────────────────────────────────────────────
   Owner-uploaded photos standing in for a typed-out menu / timeline. Rendered
   by guest::partials.section-images, which is identical in all five templates
   — as with the gallery tiles, only the styling below and each template's
   overrides differ.

   Menu cards are usually portrait phone photos, so images run full width in a
   single column and cap their height; the lightbox is where they get read. */
.gt-secimg { display: grid; gap: 1rem; }
.gt-secimg__item { margin: 0; }
.gt-secimg__link {
    position: relative; display: block;
    border-radius: .9rem; overflow: hidden;
    border: 1px solid rgba(0, 0, 0, .08);
    background: rgba(0, 0, 0, .02);
    line-height: 0;
}
.gt-secimg__img {
    display: block; width: 100%; height: auto;
    max-height: 80vh; object-fit: contain;
}
.gt-secimg__zoom {
    position: absolute; right: .55rem; bottom: .55rem;
    display: flex; align-items: center; justify-content: center;
    width: 2rem; height: 2rem; border-radius: 50%;
    background: rgba(0, 0, 0, .55); color: #fff;
    font-size: .75rem; line-height: 1;
    opacity: 0; transition: opacity .15s ease;
    pointer-events: none;
}
.gt-secimg__link:hover .gt-secimg__zoom,
.gt-secimg__link:focus-visible .gt-secimg__zoom { opacity: 1; }
/* Touch devices never hover — keep the affordance permanently visible there. */
@media (hover: none) {
    .gt-secimg__zoom { opacity: .85; }
}
.gt-secimg__link:focus-visible {
    outline: 2px solid var(--ev-accent, #317265); outline-offset: 2px;
}
.gt-secimg__caption {
    margin: .5rem .15rem 0;
    font-size: .8rem; opacity: .65; text-align: center;
}

/* ── Upload progress toast ───────────────────────────────────────────────
   Shared by all five templates. The bar itself (.es-uprog) ships with
   partials/upload-progress.blade.php, because the owner panel renders the
   same one; only this surrounding card is guest-specific.

   Pinned to the bottom so it stays readable while the guest keeps scrolling
   the gallery, and above the templates that put chrome down there (Feed's
   bottom nav, Mosaic's dock) rather than under it. */
.gt-uprog {
    position: fixed;
    left: 50%;
    bottom: max(1rem, env(safe-area-inset-bottom));
    transform: translateX(-50%);
    z-index: 60;
    width: min(22rem, calc(100vw - 2rem));
    padding: .75rem .9rem;
    border-radius: 14px;
    background: #fff;
    color: #1f2937;
    box-shadow: 0 10px 30px -8px rgba(0, 0, 0, .35);
    border: 1px solid rgba(0, 0, 0, .06);
}
.gt-uprog__text {
    margin: 0 0 .5rem;
    font-size: .8rem;
    font-weight: 500;
    line-height: 1.35;
}
/* A failure has no percentage to show, so the bar goes and the message takes
   the whole card. Tapping it dismisses. */
.gt-uprog--error {
    cursor: pointer;
    border-color: rgba(220, 38, 38, .3);
    color: #b91c1c;
}
.gt-uprog--error .gt-uprog__text { margin-bottom: 0; }
.gt-uprog--error .es-uprog { display: none; }

/* Templates that dock something to the bottom edge need the toast lifted
   clear of it rather than floating over the controls. */
.gt-feed .gt-uprog,
.gt-wall .gt-uprog { bottom: max(5.25rem, calc(env(safe-area-inset-bottom) + 5rem)); }
