/* =============================================================================
 * Fontana Hotels — design system
 * Clean, welcoming, warm, professional, with a little depth. One component set;
 * per-hotel colours are swapped as CSS variables by core/theme.js. The signature
 * is the coloured header block + the Cormorant wordmark. Mobile-first.
 * ========================================================================== */

/* ----------------------------------------------------------------------------
 * 1. Tokens  (the §6 [DECIDED] values are kept exactly; the rest are derived)
 * -------------------------------------------------------------------------- */
:root {
  color-scheme: light;

  /* geometry (§6 fixed) */
  --radius: 12px;
  --radius-sm: 8px;
  --space: 16px;
  --maxw: 520px;
  /* geometry (added) */
  --radius-lg: 20px;
  --radius-pill: 999px;
  --radius-btn: 7px; /* buttons: almost square, small soft corners */
  --radius-card: 9px; /* content surfaces (menu, cards, panels) — ONE shared corner so everything matches */

  /* neutrals — warm (§6 fixed) */
  --ink: #15211c;
  --bg: #f7f5ef;
  --surface: #fff;
  --muted: #6b6f6a;
  --line: rgba(0, 0, 0, .10);
  /* neutrals (added) */
  --ink-soft: #44504a;
  --surface-2: #fbfaf4;
  --line-strong: rgba(0, 0, 0, .16);

  /* brand — defaults; theme.js overrides per hotel (§6 fixed) */
  --c-primary: #1d6e86;
  --c-primary-dark: #0f2a38;
  --c-accent: #e0a55a;
  --c-tint: #e9f2f4;

  /* derived brand helpers */
  --on-primary: #fff;
  --on-accent: var(--ink);
  /* soft tinted surface from the active primary — adapts to light/dark */
  --tint-bg: color-mix(in srgb, var(--c-primary) 9%, var(--surface));
  --primary-hover: color-mix(in srgb, var(--c-primary) 86%, #000);

  /* feedback */
  --danger: #a8302f;
  /* one fixed red for every close / delete / closed-day cue — deliberately NOT re-declared in
     dark mode and never color-mixed with ink/accent, so it's identical in every theme (the Manager Reset red). */
  --danger-solid: #c0322b;
  --success: #2f6b4f;

  /* elevation */
  --shadow-sm: 0 1px 2px rgba(20, 30, 25, .06), 0 1px 3px rgba(20, 30, 25, .05);
  --shadow-md: 0 2px 8px rgba(20, 30, 25, .08), 0 12px 28px rgba(20, 30, 25, .08);

  /* type */
  --font-display: var(--font-ui); /* Fraunces dropped — Inter is the one sans for everything but the wordmark */
  --font-ui: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-logo: 'Cormorant', Georgia, 'Times New Roman', serif; /* the wordmark */
  --lh: 1.55;

  /* header block — white at brand level; per-hotel views override these */
  --header-bg: var(--surface);
  --header-fg: var(--ink);

  --focus: color-mix(in srgb, var(--c-primary) 60%, #000);
}

/* Dark mode — warm charcoal, not pure black. Brand fills (primary/accent) carry
 * over; the tinted surface re-derives against the dark surface automatically. */
/* Dark mode — one token set, swapped. Applied via data-theme on <html> by the
 * inline script in index.html (saved preference; "auto" follows the system). */
:root[data-theme="dark"] {
    color-scheme: dark;
    --ink: #eef1ea;
    --ink-soft: #c3ccc4;
    --bg: #12161a;
    --surface: #1a2024;
    --surface-2: #202730;
    --muted: #9aa49d;
    --line: rgba(255, 255, 255, .12);
    --line-strong: rgba(255, 255, 255, .20);
    --on-accent: #1a1206;
    --tint-bg: color-mix(in srgb, var(--c-primary) 24%, var(--surface));
    --primary-hover: color-mix(in srgb, var(--c-primary) 80%, #fff);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-md: 0 12px 30px rgba(0, 0, 0, .5);
    --focus: color-mix(in srgb, var(--c-primary) 55%, #fff);
}

/* ----------------------------------------------------------------------------
 * 2. Reset & base
 * -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--font-ui);
  font-size: 16px;
  line-height: var(--lh);
  color: var(--ink);
  /* depth: a soft lighter pocket of the active colour up top, fading into bg */
  background:
    radial-gradient(135% 70% at 50% -8%, color-mix(in srgb, var(--c-primary) 13%, var(--bg)) 0%, transparent 58%),
    var(--bg);
  background-attachment: fixed;
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Savile Row pinstripe — a faint tailored texture behind the whole app. Fixed so
   it sits still while content scrolls; kept subtle, and fainter in light mode.
   Since 2026-07-17 it's a VARIABLE: the default stays the pinstripe, and a wizard client's
   chosen Sfondo (bg_01…bg_10, HQ picker) overrides it at boot via --app-bg on <html>. */
:root { --app-bg: url('../assets/img/savile-row-pinstripe.jpg'); }
/* The FADE below belongs to the pinstripe (the source file is too light — these low opacities
   ARE its treatment). A chosen Sfondo texture (bg_01…bg_10) is final art: the boot sets
   --app-bg-op:1 alongside --app-bg, and every rule here defers to it. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: var(--app-bg) center center / cover no-repeat;
  opacity: var(--app-bg-op, .085); /* light-mode landing — kept very faint */
}
html[data-theme="dark"] body::before { opacity: var(--app-bg-op, .42); }
/* inside pages (a hotel, or the guest Private Area): lift the pinstripe to ~40% in both themes */
html[data-theme="dark"] body:has(.app--hotel)::before,
html[data-theme="dark"] body:has(.app--guest)::before { opacity: var(--app-bg-op, .4); }
html[data-theme="light"] body:has(.app--hotel)::before,
html[data-theme="light"] body:has(.app--guest)::before { opacity: var(--app-bg-op, .24); }

img, picture, svg { max-width: 100%; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--c-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

::selection { background: color-mix(in srgb, var(--c-accent) 45%, transparent); }

/* Portrait guard — the app is portrait-only. Android installed PWAs honour the manifest orientation
   lock; iOS ignores it, so we cover the app on a phone held in landscape. Scoped to phone-sized
   landscape (short viewport) so it NEVER triggers on a tablet or desktop (which stay tall). */
.rotate-guard { display: none; }
@media (orientation: landscape) and (max-height: 500px) {
  .rotate-guard {
    display: flex; position: fixed; inset: 0; z-index: 9999;
    align-items: center; justify-content: center; padding: 24px; text-align: center;
    background: var(--bg); color: var(--ink);
  }
  .rotate-guard__inner { display: flex; flex-direction: column; align-items: center; gap: 12px; max-width: 320px; }
  .rotate-guard__inner svg { color: var(--c-primary); }
  .rotate-guard__txt { margin: 0; font-family: var(--font-ui); font-weight: 600; font-size: 16px; line-height: 1.35; color: var(--ink); }
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ----------------------------------------------------------------------------
 * 3. Typography — Fraunces for display, Inter for UI. Sentence case throughout.
 * -------------------------------------------------------------------------- */
h1, h2, h3, .display, .title {
  font-family: var(--font-display);
  font-weight: 600;
  font-optical-sizing: auto;
  line-height: 1.15;
  margin: 0;
  letter-spacing: -.01em;
}
.display { font-size: clamp(28px, 7vw, 40px); }
h1, .h1 { font-size: clamp(24px, 5.5vw, 30px); }
h2, .h2 { font-size: 20px; }
h3, .h3 { font-size: 17px; }
p { margin: 0 0 .75em; }
p:last-child { margin-bottom: 0; }

.eyebrow {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 13px;
  color: var(--muted);
  margin: 0;
}
.lead { font-size: 17px; color: var(--ink-soft); }
.muted { margin: 0; color: var(--muted); }
.small { font-size: 14px; }

/* ----------------------------------------------------------------------------
 * 4. Layout
 * -------------------------------------------------------------------------- */
.app { min-height: 100dvh; }
/* guest app: full-height column so the bottom tab bar stays pinned to the bottom
   even when a screen's content is short (otherwise it floats up mid-screen) */
.app--guest { display: flex; flex-direction: column; }
.app--guest .screen { flex: 1 0 auto; padding-bottom: calc(84px + env(safe-area-inset-bottom)); } /* clear the fixed tab bar */
.container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--space); }
.screen { padding-block: 20px calc(28px + env(safe-area-inset-bottom)); }
.stack { display: grid; gap: var(--gap, 14px); }
.cluster { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.section { margin-block: 26px; }
.section__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.section__title { font-family: var(--font-ui); font-weight: 600; font-size: 22px; }
.section__head--center { justify-content: center; }
.section__head--center .section__title { text-align: center; }
.section__logo { display: block; width: auto; height: 46px; max-width: 74%; object-fit: contain; }
.section__logo--trentino { height: 42px; }
/* the logos are white (for the dark theme); on the light theme flip them dark so they read */
html[data-theme="light"] .section__logo { filter: invert(1); }
/* big page headings (e.g. the hotel name under "Your stay") — Inter, bold */
.h1 { font-family: var(--font-ui); font-weight: 700; }
.section__link { font-size: 14px; font-weight: 600; }

/* thin inset separator between home blocks — fades out before the edges */
.rule {
  border: 0; height: 1px; width: 100%; margin: 18px 0;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb, var(--ink) 16%, transparent) 14%,
    color-mix(in srgb, var(--ink) 16%, transparent) 86%,
    transparent 100%);
}

/* ----------------------------------------------------------------------------
 * 5. The signature — the header block + wordmark
 *    A fixed block whose colour belongs to the active hotel (white at the brand
 *    level). The "Fontana Hotels" wordmark is the lockup.
 * -------------------------------------------------------------------------- */
.apphead {
  position: sticky; top: 0; z-index: 20;
  padding-top: env(safe-area-inset-top); /* clear the notch / status bar (esp. installed PWA) */
  background: var(--header-bg); color: var(--header-fg);
  border-bottom: 1px solid color-mix(in srgb, var(--header-fg) 12%, transparent);
  box-shadow: 0 4px 12px rgba(8, 16, 20, .24);
  transition: box-shadow .22s ease;
}
/* stronger lift once the page is scrolled */
html.is-scrolled .apphead { box-shadow: 0 12px 28px rgba(8, 16, 20, .46); }
.apphead__inner { display: flex; align-items: center; gap: 10px; min-height: 60px; }

/* brand level — white block, dark wordmark */
.apphead--brand { --header-bg: var(--brand-header-bg, var(--surface)); --header-fg: var(--brand-header-fg, var(--ink)); } /* a business may bring its own header colours (theme.headerBg/Fg) */

/* hotel level — the hotel's colour with a soft sheen, white wordmark */
.apphead--hotel {
  --header-fg: #fff;
  background:
    radial-gradient(120% 180% at 0% 0%, color-mix(in srgb, #fff 22%, var(--c-primary)) 0%, transparent 55%),
    linear-gradient(180deg, var(--c-primary) 0%, var(--primary-hover) 100%);
  border-bottom: 2px solid var(--c-primary-dark);
}

/* accent header — the guest "Private Area" (matches the gold banner you tapped) */
.apphead--accent {
  --header-fg: var(--on-accent);
  background:
    radial-gradient(120% 180% at 0% 0%, color-mix(in srgb, #fff 26%, var(--c-accent)) 0%, transparent 55%),
    linear-gradient(180deg, var(--c-accent) 0%, color-mix(in srgb, var(--c-accent) 86%, #000) 100%);
  border-bottom: 2px solid color-mix(in srgb, var(--c-accent) 55%, #000);
}
/* "PRIVATE AREA" header title — same look as the banner label (Inter, bold) */
.apphead__title { flex: 1; min-width: 0; text-align: center; font-family: var(--font-ui); font-weight: 800;
  font-size: 19.5px; letter-spacing: .06em; color: var(--header-fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.apphead__title--sm { font-size: clamp(15px, 4.5vw, 18px); letter-spacing: .04em; } /* longer titles that must fit (e.g. OPEN YOUR GUEST APP) */
/* guest header: "PRIVATE AREA" + the current screen name stacked underneath */
.apphead__titles { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; }
.apphead__titles .apphead__title { flex: none; max-width: 100%; }
.apphead__sub { font-family: var(--font-display); font-style: italic; font-size: 15px; line-height: 1.25;
  color: var(--on-accent); max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* hotel-name header — sized to fit the full "Hotel ..." name, with line-height
   that leaves room for descenders (g, p) so they aren't clipped by overflow */
/* One size for every hotel name, tuned so the longest ("Hotel Cesare Augusto")
   always fits between the back + menu icons with margin — never truncates. */
.apphead--hotel .wordmark--center { font-family: var(--font-ui); font-weight: 700; letter-spacing: -.01em; font-size: clamp(17px, 5.6vw, 24px); line-height: 1.12; }

.wordmark {
  font-family: var(--font-logo);
  font-weight: 600; font-size: 31px; line-height: 1; letter-spacing: .015em;
  color: var(--header-fg); white-space: nowrap;
}
/* "Hotels" in green italic, matching the wordmark on the unlock page */
.wordmark em { font-style: italic; font-weight: 600; color: #2f6b4f; opacity: 1; }
.apphead--hotel .wordmark em { color: inherit; } /* on a coloured header keep it white */
@media (prefers-color-scheme: dark) { .wordmark em { color: #6aa886; } }
.wordmark--sm { font-size: 22px; }
.wordmark--center { flex: 1; text-align: center; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* landing hero header — a cream "letterhead" block (fixed light in both modes) */
.landing-head { background: var(--brand-header-bg, #f6f3ec); color: var(--brand-header-fg, #15211c); border-bottom: 1px solid #2f6b4f; position: relative; } /* a business's own header colours win; the classic cream is the fallback. 1px divider (was 2px — too heavy) */
/* Settings gear, bottom-right of the cream branding bar — anchored to the BOTTOM so it always lands on
   the name row (compact) / tagline row (full) and never rides up into the notch / status-bar safe area.
   The header is ALWAYS cream (both themes), so the gear uses a FIXED dark colour — var(--ink) would go
   light in dark mode → invisible here. */
/* Settings gear — TOP-right corner (below the notch/status-bar via safe-area). Out of the centred logo +
   payoff column, so a payoff line of ANY length (Super-Admin editable) never runs under it. */
.apphead__set { position: absolute; right: 10px; top: calc(env(safe-area-inset-top) + 8px); z-index: 3; width: 40px; height: 40px; display: grid; place-items: center; color: color-mix(in srgb, var(--header-fg, #15211c) 55%, transparent); border-radius: 999px; text-decoration: none; -webkit-tap-highlight-color: transparent; }
/* NEVER underline the gear — the global `a:hover{text-decoration:underline}` (which iOS makes stick on
   tap) outranks the base rule above, so override it explicitly in every interactive state. */
.apphead__set:hover, .apphead__set:active, .apphead__set:focus, .apphead__set:visited { text-decoration: none; }
.apphead__set:active { color: color-mix(in srgb, var(--header-fg, #15211c) 78%, transparent); background: color-mix(in srgb, var(--header-fg, #15211c) 6%, transparent); }
.landing-head__inner { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px; padding: 2px 0 18px; } /* full (Home) header: logo higher; bottom pad (+3px → taller header, more empty space under the payoff) (Tony) */
.landing-head__logo + .landing-head__title { margin-top: -11px; } /* pull the payoff up toward the logo's ornament (Tony: up another 2px) */
.wordmark--hero { font-size: clamp(40px, 14vw, 62px); line-height: 1.02; color: #15211c; white-space: nowrap; }
.landing-head .wordmark--hero em { color: #2f6b4f; } /* green italic, fixed in both modes */
.landing-head__rule { width: 100%; max-width: 380px; height: 2px; border-radius: 2px; margin: 3px 0 5px;
  background: linear-gradient(90deg, transparent, #2f6b4f 12%, #2f6b4f 88%, transparent); }
.landing-head__title { font-family: var(--font-ui); font-weight: 600; font-size: 23px; color: var(--header-fg, #15211c); margin: 0; line-height: 1.2; }
.landing-head__sub { font-family: var(--font-display); font-style: italic; font-size: 15px; color: color-mix(in srgb, var(--header-fg, #15211c) 60%, transparent); margin: 0; line-height: 1.25; }
/* compact header — inner pages (Menu, Speciali, Impostazioni…): just the name/logo, a touch smaller,
   with no rule / payoff line / tagline. The full header stays on Home + Contatti. */
.landing-head--compact .landing-head__inner { padding: 2px 0 3px; gap: 0; } /* compact (inner pages): logo higher + shorter header (Tony) */
.landing-head--compact .wordmark--hero { font-size: clamp(26px, 8.5vw, 38px); }
.landing-head--compact .landing-head__logo { width: auto; height: calc(54px * var(--logo-scale, 1)); max-width: 78%;
  padding: 7px 0; box-sizing: border-box; object-fit: contain; } /* compact: size by HEIGHT; 7px top/bottom breathing space (Tony 2026-07-17 — a full-bleed PNG/SVG used to touch both edges; 5px → 7px same day) */

/* bare white icon button on a coloured header — no circle, like the banner arrow */
.iconbtn.iconbtn--on-color { color: #fff; background: transparent; }
.iconbtn.iconbtn--on-color:hover { background: rgba(255, 255, 255, .14); }
/* labeled icon button (the "Exit" button in the guest header) + a matching left spacer so the title stays centred */
.iconbtn--labeled { width: 48px; height: auto; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 4px 0; border-radius: 10px; }
.iconbtn__label { font-size: 10px; font-weight: 600; line-height: 1; letter-spacing: .03em; }
.apphead__spacer { flex: none; width: 48px; }
.iconbtn.iconbtn--on-accent { color: var(--on-accent); background: transparent; }
.iconbtn.iconbtn--on-accent:hover { background: rgba(0, 0, 0, .10); }

/* ----------------------------------------------------------------------------
 * 6. Buttons
 * -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-ui); font-weight: 600; font-size: 15px; line-height: 1;
  min-height: 46px; padding: 0 20px;
  border: 1px solid transparent; border-radius: var(--radius-btn);
  background: var(--surface-2); color: var(--ink); cursor: pointer;
  transition: background-color .18s ease, border-color .18s ease, transform .06s ease, box-shadow .18s ease;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: default; box-shadow: none; transform: none; }
/* primary — gradient + a soft side glow + glossy top edge for life */
.btn--primary {
  color: var(--on-primary);
  border-color: color-mix(in srgb, #000 16%, var(--c-primary)); /* thin crisp edge */
  background:
    linear-gradient(108deg, color-mix(in srgb, #fff 26%, var(--c-primary)) 0%, var(--c-primary) 42%, var(--primary-hover) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .28),
    0 6px 18px color-mix(in srgb, var(--c-primary) 38%, transparent);
}
.btn--primary:hover { filter: brightness(1.04); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .32), 0 8px 22px color-mix(in srgb, var(--c-primary) 46%, transparent); }
.btn--secondary { background: var(--surface); color: var(--ink); border-color: color-mix(in srgb, var(--ink) 18%, transparent); }
.btn--secondary:hover { background: var(--surface-2); border-color: var(--muted); }
.btn--ghost { background: transparent; color: var(--c-primary); }
.btn--ghost:hover { background: var(--tint-bg); }
.btn--accent {
  color: var(--on-accent);
  background: linear-gradient(108deg, color-mix(in srgb, #fff 32%, var(--c-accent)) 0%, var(--c-accent) 55%, color-mix(in srgb, var(--c-accent) 82%, #000) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 6px 16px color-mix(in srgb, var(--c-accent) 40%, transparent);
}
.btn--accent:hover { filter: brightness(1.03); }
/* WhatsApp — the one true brand green (#25D366), so "message us" reads instantly. Matches the app's glossy finish. */
.btn--whatsapp {
  color: #fff;
  border-color: color-mix(in srgb, #000 16%, #25D366);
  background: linear-gradient(108deg, color-mix(in srgb, #fff 24%, #25D366) 0%, #25D366 46%, #1cb457 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .30), 0 6px 16px color-mix(in srgb, #25D366 40%, transparent);
}
.btn--whatsapp:hover { filter: brightness(1.03); }
/* item 4 — customer splash: the owner's INLINE image paints on the first frame (no download); an opaque
   cover (= app bg) sits behind it so the app never flashes underneath; only the dismiss fades it out. */
.app-splash { position: fixed; inset: 0; z-index: 9000; background-color: var(--bg, #14181a);
  background-position: center; background-size: cover; background-repeat: no-repeat; transition: opacity .4s ease; }
.app-splash.is-out { opacity: 0; pointer-events: none; }
.btn--block { width: 100%; }
.btn--sm { min-height: 38px; padding: 0 14px; font-size: 14px; }
.btn[disabled], .btn:disabled { opacity: .5; cursor: not-allowed; }
.btn i { font-size: 18px; }

/* icon-only round button (app bar) */
.iconbtn {
  display: inline-grid; place-items: center; width: 42px; height: 42px;
  border-radius: var(--radius-pill); border: 1px solid transparent;
  background: transparent; color: var(--ink); cursor: pointer;
  transition: background-color .18s ease;
  -webkit-tap-highlight-color: transparent; /* no lingering colour flash on iOS tap */
}
/* hover tint only where a real pointer exists — avoids the sticky "brown circle" on touch */
@media (hover: hover) { .iconbtn:hover { background: var(--tint-bg); } }
.iconbtn i { font-size: 22px; }

/* ----------------------------------------------------------------------------
 * 7. Cards
 * -------------------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.card__media { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.card__body { padding: 16px; }
.card__title { font-family: var(--font-display); font-weight: 600; font-size: 18px; margin: 0 0 4px; }

/* tinted "offer" card — the daily-offer money shot leans on this */
.card--tint { background: var(--tint-bg); border-color: color-mix(in srgb, var(--c-primary) 18%, transparent); }
.card--feature { box-shadow: var(--shadow-md); }
/* Specialità: keep the price pinned to the right and let a long description wrap to a 2nd line
   inside its own column — the price must never wrap onto a new row below the photo. */
.card--feature .card__body { flex-wrap: nowrap; align-items: center; }
.card--feature .card__body > .cluster { flex: 1 1 auto; min-width: 0; flex-wrap: nowrap; }
.card--feature .row__sub { white-space: normal; }
.card--feature .price { flex: none; white-space: nowrap; }

/* offer card — square photo flush to the left edge, copy left-aligned beside it */
.offer-card { position: relative; display: flex; align-items: stretch; overflow: hidden; text-decoration: none; color: inherit;
  background: var(--tint-bg); border: 1px solid color-mix(in srgb, var(--c-primary) 18%, transparent); border-radius: var(--radius-card); }
.offer-card:hover { text-decoration: none; }
.offer-card__img { width: 112px; flex: none; object-fit: cover; align-self: stretch; }
.offer-card__body { padding: 14px 42px 14px 16px; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* Offer titles: a touch larger, and never wrap — a JS pass (fitOfferTitles) shrinks any title that
   would spill so it always sits on a single row. overflow:hidden is the safety net if JS is off. */
.offer-card .card__title { font-size: 20px; white-space: nowrap; overflow: hidden; }

/* ☆ save-to-My-Extras control, top-right of the card; gold ★ when saved, × on the My Extras page */
.offer-star { position: absolute; top: 6px; right: 6px; z-index: 2; width: 36px; height: 36px;
  display: grid; place-items: center; cursor: pointer; color: var(--muted);
  transition: color .15s ease, transform .12s ease; }
.offer-star i { font-size: 23px; }
.offer-star .estar { width: 23px; height: 23px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linejoin: round; }
.offer-star.is-saved .estar { fill: currentColor; stroke: none; }
.offer-star:hover, .offer-star.is-saved { color: var(--c-accent); }
.offer-star:active { transform: scale(.85); }

/* ----------------------------------------------------------------------------
 * Speciali & Eventi — colour-coded feed cards (restaurant customer app). Each card
 * takes on its Tipo's identity: a soft pastel wash across the WHOLE card (bg, border,
 * badge, title, date, chevron) via the inline --tipo custom property (from
 * SPECIALI_TIPI). Independent of the app style, so the colour always leads.
 * -------------------------------------------------------------------------- */
.spec-feed { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.spec-card { --tipo: var(--c-primary);
  position: relative; display: block; min-width: 0; overflow: hidden;
  text-decoration: none; color: inherit; cursor: pointer;
  background: color-mix(in srgb, var(--tipo) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--tipo) 30%, var(--line));
  border-radius: var(--radius-card);
  transition: border-color .15s ease, transform .08s ease;
}
.spec-card:active { transform: scale(.994); }
.spec-card__expiry { display: flex; align-items: center; justify-content: center; gap: 5px; padding: 7px 12px;
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em; color: color-mix(in srgb, var(--tipo) 55%, var(--muted));
  border-top: 1px solid color-mix(in srgb, var(--tipo) 18%, var(--line)); }
.spec-card__expiry i { font-size: 13px; }
/* left rail — the photo, or a tinted tile bearing the tipo icon. ABSOLUTELY positioned so its own
   height can never grow the card: it always fills the (text-driven) card height, cropped. This keeps
   every card the same height regardless of the uploaded photo's proportions, and 96px-pinned so it
   can never widen past the edge either. */
.spec-card__img, .spec-card__img--ph { position: absolute; left: 0; top: 0; bottom: 0; width: 96px; height: 100%; }
.spec-card__img { object-fit: cover; }
.spec-card__img--ph { display: grid; place-items: center;
  background: color-mix(in srgb, var(--tipo) 20%, var(--surface));
  color: color-mix(in srgb, var(--tipo) 80%, var(--ink)); }
.spec-card__body { margin-left: 96px; min-width: 0; overflow: hidden; padding: 12px 14px;
  display: flex; flex-direction: column; gap: 5px; }
/* the colour-coded Tipo badge: [icon] Label · €cost */
.spec-badge { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%;
  padding: 3px 11px; border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--tipo) 22%, var(--surface));
  color: color-mix(in srgb, var(--tipo) 82%, var(--ink));
  font-family: var(--font-ui); font-size: 12px; font-weight: 700; letter-spacing: .01em; white-space: nowrap; }
.spec-badge i { font-size: 15px; flex: none; }
.spec-badge__label { overflow: hidden; text-overflow: ellipsis; }
/* the price rides its own solid chip inside the badge — a "price tag", louder than the type label */
.spec-badge:has(.spec-badge__cost) { padding-right: 4px; }
.spec-badge__cost { flex: none; margin-left: 3px; padding: 2px 10px; font-weight: 800; font-size: 14.5px;
  background: var(--tipo); color: #fff; border-radius: var(--radius-pill); }
.spec-card__title { font-family: var(--font-display); font-weight: 600; font-size: 19px; line-height: 1.15; margin: 1px 0 0;
  color: color-mix(in srgb, var(--tipo) 22%, var(--ink)); overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* date UNDER the title, in the SAME colour as the title (not a brighter accent) */
.spec-card__date { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font-family: var(--font-ui); font-size: 12.5px; font-weight: 600;
  color: color-mix(in srgb, var(--tipo) 22%, var(--ink)); }
.spec-card__date i { font-size: 14px; }
.spec-card__more { display: flex; align-items: center; gap: 8px; margin-top: 1px; }
.spec-card__desc { flex: 1 1 auto; min-width: 0; margin: 0; overflow-wrap: anywhere;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: 14px; line-height: 1.3; color: var(--muted); }
.spec-card__chev { flex: none; display: inline-flex; color: color-mix(in srgb, var(--tipo) 60%, var(--muted)); }
/* the date line inside the full-view card modal (kept under the title there) */
.spec-card__when { display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-ui); font-size: 12.5px; font-weight: 600;
  color: color-mix(in srgb, var(--tipo) 60%, var(--ink)); }
.spec-card__when i { font-size: 14px; }

/* TRACK U — the head (photo + text) keeps its own positioning context + min height so the offer
   band can sit full-width BELOW it (inside the card); the absolute photo fills only the head. */
.spec-card__head { position: relative; min-height: 104px; }
/* "Usa l'offerta" band — a centred strip inside the card that matches the card's own tipo colour,
   with a ticket-notch edge, a big boxless present icon, and a softly glowing CTA. */
.spec-offer { position: relative; padding: 14px 14px 15px; display: flex; flex-direction: column; align-items: center; gap: 7px; text-align: center;
  border-top: 1px dashed color-mix(in srgb, var(--tipo) 48%, var(--line));
  background:
    radial-gradient(circle at 0 0, transparent 7px, var(--_ofc) 7.5px) left top / 51% 100% no-repeat,
    radial-gradient(circle at 100% 0, transparent 7px, var(--_ofc) 7.5px) right top / 51% 100% no-repeat;
  --_ofc: color-mix(in srgb, var(--tipo) 16%, var(--surface)); }
.spec-offer__gift { color: var(--tipo); line-height: 1; }
.spec-offer__gift i { font-size: 42px; }
.spec-offer__k { font-size: 10.5px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: color-mix(in srgb, var(--tipo) 82%, var(--ink)); }
.spec-offer__v { font-size: 22px; font-weight: 800; letter-spacing: -.2px; color: var(--ink); overflow-wrap: anywhere; margin-top: -3px; }
.spec-offer__btn { position: relative; width: 100%; margin-top: 4px; border: 0; border-radius: var(--radius-btn); background: var(--tipo); color: #fff;
  font-family: var(--font-ui); font-weight: 800; font-size: 15px; padding: 12px; cursor: pointer; text-transform: uppercase;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; -webkit-tap-highlight-color: transparent; }
.spec-offer__btn i { font-size: 18px; }
.spec-offer__btn:active { transform: translateY(1px); }
/* soft pulsing glow — on a pseudo-element so its colour is the card's --tipo: a normal declaration
   resolves var() per-element (unlike var() inside @keyframes, which Chromium resolves against the
   base). The keyframe animates only opacity, which can't break. */
.spec-offer__btn::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: 0 0 16px 0 color-mix(in srgb, var(--tipo) 55%, transparent);   /* spread 0 → glow sits only OUTSIDE the button */
  animation: spec-offer-glow 2.2s ease-in-out infinite; }  /* unique name — an offer-glow keyframe already exists (guest app) */
@keyframes spec-offer-glow { 0%, 100% { opacity: .2; } 50% { opacity: .9; } }
@media (prefers-reduced-motion: reduce) { .spec-offer__btn::after { animation: none; opacity: .45; } }
.spec-offer__hint { display: inline-flex; align-items: center; justify-content: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: color-mix(in srgb, var(--tipo) 82%, var(--ink)); }
.spec-offer__hint i { font-size: 14px; }
.spec-offer--used { background: color-mix(in srgb, var(--success) 10%, var(--surface)); align-items: center; }
.spec-offer__usedtag { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 700; color: var(--success); }
/* TRACK U Phase 2 — the automatic-offer banner (Benvenuto / Torna a trovarci) at the top of Home.
   A warm, tappable "gift from the venue" strip, tinted with its own --ao house colour (set inline). */
.auto-offer { position: relative; width: 100%; display: flex; align-items: center; gap: 14px; text-align: left;
  margin-bottom: 18px; padding: 14px; border-radius: var(--radius-card); cursor: pointer; font-family: inherit;
  -webkit-tap-highlight-color: transparent;
  border: 1px solid color-mix(in srgb, var(--ao) 42%, var(--line));
  background: linear-gradient(135deg, color-mix(in srgb, var(--ao) 15%, var(--surface)), color-mix(in srgb, var(--ao) 6%, var(--surface)));
  box-shadow: 0 7px 20px -12px color-mix(in srgb, var(--ao) 60%, transparent); }
.auto-offer:active { transform: translateY(1px); }
.auto-offer__glyph { flex: none; width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center;
  color: #fff; background: var(--ao); box-shadow: 0 3px 10px -3px color-mix(in srgb, var(--ao) 70%, transparent); }
.auto-offer__glyph i { font-size: 28px; }
.auto-offer__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.auto-offer__title { font-weight: 800; font-size: 21px; letter-spacing: -.4px; color: var(--ink); line-height: 1.1;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.auto-offer__title i { color: var(--ao); }
.auto-offer__deal { font-weight: 800; font-size: 15px; letter-spacing: -.2px; color: var(--ao); }
.auto-offer__body { font-size: 13px; color: var(--muted); line-height: 1.3; }
/* Carta Punti (TRACK U Phase 3) — customer loyalty screen */
.carta-hero { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 3px; padding: 22px 16px; border-radius: var(--radius-card);
  background: linear-gradient(135deg, color-mix(in srgb, var(--c-primary) 16%, var(--surface)), color-mix(in srgb, var(--c-primary) 5%, var(--surface)));
  border: 1px solid color-mix(in srgb, var(--c-primary) 30%, var(--line)); }
.carta-hero__k { font-size: 15px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--c-primary); }
.carta-hero__n { font-size: 54px; font-weight: 800; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; display: inline-flex; align-items: baseline; gap: 9px; }
.carta-hero__u { font-size: 21px; font-weight: 700; color: var(--muted); }
.carta-hero__msg { font-size: 13.5px; color: var(--muted); margin: 10px 0 0; display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; justify-content: center; }
.carta-hero__msg i { color: var(--c-primary); }
.carta-stamps { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; align-items: center; margin-top: 12px; max-width: 238px; }  /* fits exactly 7 stamps per row (7×26 + 6×8) */
.carta-stamp { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; border: 1.5px dashed color-mix(in srgb, var(--c-primary) 40%, var(--line)); color: color-mix(in srgb, var(--c-primary) 45%, var(--muted)); }
.carta-stamp.is-on { background: var(--c-primary); border-color: var(--c-primary); color: #fff; }
/* the premio stamp (the 10/20/30 milestone, last of the row): GOLD and a bit bigger than the others */
.carta-stamp--premio { width: 32px; height: 32px; border: 2px dashed color-mix(in srgb, #d9a23c 70%, transparent); color: #d9a23c; }
.carta-stamp--premio.is-on { background: #d9a23c; border-color: #d9a23c; color: #fff; box-shadow: 0 0 12px color-mix(in srgb, #d9a23c 45%, transparent); }
.carta-bar { width: 82%; max-width: 300px; height: 10px; border-radius: 999px; margin-top: 14px; overflow: hidden; background: color-mix(in srgb, var(--c-primary) 16%, var(--surface)); }
.carta-bar__fill { display: block; height: 100%; border-radius: 999px; background: var(--c-primary); }
/* the "‹ tipi predefiniti" escape under the custom-tipo text field (Speciali form) */
.tipo-back { margin-top: 6px; background: none; border: 0; padding: 0 2px; font: inherit; font-size: 11.5px; color: var(--muted); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }

/* Home push-notification invite: one calm row, one tap = the iOS permission dialog */
.notif-invite { display: flex; align-items: center; gap: 12px; padding: 12px 14px; margin-bottom: 16px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); }
.notif-invite__icon { flex: none; width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center; background: color-mix(in srgb, #d9a23c 16%, transparent); color: #d9a23c; }
/* the bell gives a gentle ring every few seconds (gold, swinging from its crown) */
.notif-invite__icon i { animation: bell-ring 4.5s ease-in-out infinite; transform-origin: 50% 10%; }
@keyframes bell-ring {
  0%, 12%, 100% { transform: rotate(0); }
  2% { transform: rotate(14deg); } 4% { transform: rotate(-12deg); }
  6% { transform: rotate(9deg); } 8% { transform: rotate(-6deg); } 10% { transform: rotate(3deg); }
}
@media (prefers-reduced-motion: reduce) { .notif-invite__icon i { animation: none; } }
.notif-invite__t span i { color: var(--muted); vertical-align: -1px; }
.notif-invite__t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.notif-invite__t strong { font-size: 14.5px; }
.notif-invite__t span { font-size: 12px; color: var(--muted); line-height: 1.35; }
.notif-invite__x { flex: none; background: none; border: 0; color: var(--muted); cursor: pointer; padding: 6px; display: grid; place-items: center; }

/* print-materials picker (Condividi → Materiali da stampare): 4 live mini-previews */
.pm-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.pm-item { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 12px 8px 10px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; cursor: pointer; font: inherit; color: inherit; }
.pm-item:active { transform: scale(.97); }
.pm-thumb { display: grid; place-items: center; height: 86px; max-width: 100%; }
.pm-thumb > svg { height: 86px; width: auto; max-width: 118px; display: block; border-radius: 3px; box-shadow: 0 4px 14px rgba(0, 0, 0, .28); }
.pm-label { font-size: 12.5px; font-weight: 650; text-align: center; line-height: 1.25; }

/* the card's own code (like the number printed on a physical loyalty card) + the recovery way back.
   Folded by default behind the quiet "Codice recupero carta" toggle. */
.carta-code-toggle { margin-top: 14px; background: none; border: 0; padding: 4px 6px; font: inherit; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.carta-code-toggle i { transition: transform .18s ease; }
.carta-code-toggle[aria-expanded="true"] i { transform: rotate(180deg); }
.carta-code { margin-top: 10px; padding-top: 14px; border-top: 1px dashed var(--line); display: flex; flex-direction: column; align-items: center; gap: 2px; align-self: stretch; }
.carta-code[hidden] { display: none; }   /* the author display:flex would otherwise defeat the hidden attribute */
.carta-code__label { font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.carta-code__v { font-size: 19px; font-weight: 750; letter-spacing: .12em; color: var(--ink); font-variant-numeric: tabular-nums; }
.carta-code__note { font-size: 11px; line-height: 1.5; color: var(--muted); max-width: 36ch; text-align: center; margin: 5px 0 0; }
.carta-recover-link { margin-top: 10px; background: none; border: 0; padding: 4px 6px; font: inherit; font-size: 12.5px; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.carta-recover__help { font-size: 13.5px; color: var(--muted); text-align: center; margin: 0 0 12px; }
.carta-recover__input { width: 100%; padding: 13px; border: 1px solid var(--line); border-radius: 12px; font: inherit; font-size: 19px; font-weight: 650; letter-spacing: .16em; text-align: center; text-transform: uppercase; color: var(--ink); background: var(--surface); font-variant-numeric: tabular-nums; }
.carta-recover__input:focus { outline: none; border-color: #c98a2b; box-shadow: 0 0 0 3px color-mix(in srgb, #c98a2b 22%, transparent); }
.carta-recover__err { color: var(--danger, #c0392b); font-size: 12.5px; text-align: center; min-height: 1.1em; margin: 8px 0 10px; }
.carta-recover__foot { font-size: 11px; color: var(--muted); text-align: center; margin: 12px 0 0; }
.carta-reward { display: flex; align-items: center; gap: 13px; padding: 12px 14px; border-radius: var(--radius-card); background: var(--surface); border: 1px solid var(--line); }
.carta-reward--ok { border-color: color-mix(in srgb, #d99326 55%, var(--line)); box-shadow: 0 0 0 1px color-mix(in srgb, #d99326 35%, transparent), 0 4px 20px color-mix(in srgb, #d99326 22%, transparent); }
.carta-reward--claimed { opacity: .55; }
.carta-reward__badge { flex: none; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; font-weight: 800; font-size: 16px; font-variant-numeric: tabular-nums; color: #fff; background: color-mix(in srgb, var(--muted) 50%, var(--surface)); }
.carta-reward--ok .carta-reward__badge { background: #d99326; }
.carta-reward__t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.carta-reward__name { font-weight: 700; font-size: 16px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.carta-reward__sub { font-size: 12.5px; color: var(--muted); }
.carta-reward--ok .carta-reward__sub { color: #d99326; font-weight: 700; }
.carta-reward__lock, .carta-reward__done { flex: none; display: grid; place-items: center; color: var(--muted); }
.carta-reward__done { color: var(--success); }
/* icon-only tab (Impostazioni) — a slim, vertically-centred gear so the 6th tab fits */
.tab--icon { flex: 0 0 46px; align-content: center; }
.tab--icon i { font-size: 22px; }
/* a capped switch (e.g. "Mostra in Home" once 3 are chosen) reads as unavailable */
.switch.is-disabled { opacity: .4; }
/* Speciali page header: the title (left) + a Tipo filter dropdown (right, same row) */
.spec-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.spec-filter { display: inline-flex; align-items: center; gap: 6px; flex: none;
  padding: 6px 8px 6px 11px; border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--muted); }
.spec-filter i { font-size: 15px; flex: none; }
.spec-filter__sel { border: 0; background: none; color: var(--ink); font-family: var(--font-ui);
  font-size: 13px; font-weight: 600; cursor: pointer; padding: 0 2px; max-width: 42vw;
  -webkit-appearance: none; appearance: none; }
.spec-filter__sel:focus { outline: none; }
/* "Vedi tutti" link on the Home teaser header */
.link-more { display: inline-flex; align-items: center; gap: 1px; font-size: 13px; font-weight: 600;
  color: var(--c-primary); text-decoration: none; white-space: nowrap; }
.link-more i { font-size: 15px; }
/* badge reused inside the full-view card modal */
.spec-badge--modal { align-self: flex-start; margin-bottom: 6px; }
.offer-star--remove { color: color-mix(in srgb, var(--muted) 85%, transparent); }
.offer-star--remove:hover { color: var(--danger-solid); }

/* soft pulsing glow for the daily-offer card — themed warm gold/yellow accent */
.offer-glow {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-accent) 45%, transparent), 0 0 14px 1px color-mix(in srgb, var(--c-accent) 38%, transparent);
  animation: offer-glow 2.6s ease-in-out infinite;
}
@keyframes offer-glow {
  0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-accent) 38%, transparent), 0 0 8px 0 color-mix(in srgb, var(--c-accent) 30%, transparent); }
  50% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-accent) 60%, transparent), 0 0 22px 3px color-mix(in srgb, var(--c-accent) 52%, transparent); }
}

/* ---- Hotel photo card (landing centrepiece). Set --card-accent inline to the
 *      hotel's primary so the border + glow belong to that hotel. ---- */
.hotel-card {
  --card-accent: var(--c-primary);
  position: relative; display: block; color: #fff; text-decoration: none;
  border-radius: var(--radius-lg); overflow: hidden; aspect-ratio: 1 / 1; isolation: isolate;
  width: 72%; max-width: 340px; margin-inline: auto;
  border: 2px solid rgba(255, 255, 255, .35); /* same on every card, softened; green in light mode (below) */
  box-shadow:
    0 22px 46px rgba(0, 0, 0, .5),
    0 8px 18px rgba(0, 0, 0, .34);
  transition: box-shadow .25s ease, transform .25s ease;
}
html[data-theme="light"] .hotel-card {
  border-color: rgba(47, 107, 79, .45); /* the "Hotels" green, softened */
  box-shadow: 0 20px 40px rgba(20, 33, 28, .24), 0 7px 16px rgba(20, 33, 28, .16);
}
.hotel-card > img { /* the background photo only — not the logo inside __body */
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: -2; transition: transform .5s ease;
}
.hotel-card::after { /* semi-transparent dark panel over the bottom half (page-bg colour @ ~84%) */
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; top: 50%; z-index: -1;
  background: rgba(18, 22, 26, .84);
}
.hotel-card:hover { text-decoration: none; transform: translateY(-2px); box-shadow: 0 30px 60px rgba(0, 0, 0, .55), 0 12px 24px rgba(0, 0, 0, .38); }
.hotel-card:hover > img { transform: scale(1.045); }
.hotel-card__body { position: absolute; left: 0; right: 0; bottom: 0; top: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 10px 16px; }
.hotel-card__name { font-family: var(--font-display); font-weight: 600; font-size: 21px; line-height: 1.1; }
.hotel-card__meta { font-size: 13px; opacity: .92; margin-top: 3px; }
.hotel-card__logo { display: block; width: var(--logo-w, 56%); height: auto; max-width: 88%; max-height: 86%; object-fit: contain; }
.hotel-card__badge {
  position: absolute; top: 12px; left: 12px; z-index: 1;
  background: rgba(255, 255, 255, .94); color: #15211c; /* fixed dark: pill is always white */
  font-size: 12px; font-weight: 600; padding: 5px 10px; border-radius: var(--radius-pill);
}

/* ----------------------------------------------------------------------------
 * 8. List rows  (services, dashboard tiles)
 * -------------------------------------------------------------------------- */
.row {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
  width: 100%; text-align: left; color: inherit; cursor: pointer;
  transition: border-color .18s ease, background-color .18s ease;
}
a.row, button.row { font: inherit; }
.row:hover { border-color: var(--line-strong); text-decoration: none; }
/* a whole item that opens its editor on tap — press feedback confirms the gesture (the 3-dots still works) */
.row--tap { -webkit-tap-highlight-color: transparent; }
.row--tap:active { background: var(--surface-2); border-color: var(--line-strong); }
.row__icon {
  flex: none; width: 42px; height: 42px; display: grid; place-items: center;
  border-radius: var(--radius-sm); background: var(--tint-bg); color: var(--c-primary);
}
.row__icon i { font-size: 22px; }
/* on the public hotel "website" pages, only the icon glyph takes the secondary
   (accent) colour; the square keeps its original (primary) tint */
.app--hotel .row__icon { color: var(--c-accent); }
/* same in the guest app — icons take the hotel's accent (the colourful "Your
   stay" icons set their own colour inline, so they override this) */
.app--guest .row__icon { color: var(--c-accent); }
.row__text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.row__title { font-weight: 600; }
.row__sub { color: var(--muted); font-size: 14px; line-height: 1.4; }
.row__chev { color: var(--muted); }
.row__chev i { font-size: 20px; }
/* "My Extras" feature row — the prominent first item in My Stay (accent-framed) */
.row--extras { border-color: color-mix(in srgb, var(--c-accent) 55%, var(--line));
  background: color-mix(in srgb, var(--c-accent) 9%, var(--surface)); }
.row--extras:hover { border-color: var(--c-accent); }
.row__icon--star .estar { width: 23px; height: 23px; fill: currentColor; }
/* × remove button on a My Extras stay row */
.row__x { flex: none; width: 36px; height: 36px; display: grid; place-items: center; border: 0; background: transparent;
  color: var(--muted); cursor: pointer; border-radius: 50%; transition: color .15s ease, background-color .15s ease; }
.row__x:hover { color: var(--danger-solid); background: color-mix(in srgb, var(--danger-solid) 12%, transparent); }
.row__x i { font-size: 20px; }

/* rooms accordion — tap a room to reveal its photo + details (single-open) */
.room { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; transition: border-color .18s ease; }
.room:hover, .room.is-open { border-color: var(--line-strong); }
.room__head { width: 100%; display: flex; align-items: center; gap: 12px; padding: 14px 16px; background: none; border: 0; cursor: pointer; text-align: left; color: inherit; font: inherit; }
.room__chev { flex: none; display: grid; place-items: center; color: var(--c-accent); transition: transform .25s ease; }
.room__chev i { font-size: 20px; }
.room.is-open .room__chev { transform: rotate(180deg); }
.room__panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .3s ease; }
.room.is-open .room__panel { grid-template-rows: 1fr; }
.room__panel-inner { overflow: hidden; min-height: 0; }
.room__img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; border-top: 1px solid var(--line); }
.room__desc { margin: 0; padding: 13px 16px 15px; color: var(--muted); font-size: 14px; line-height: 1.5; }

/* hero photo on a hotel page wears the same border as the landing cards (continuity) */
.hotel-hero { border: 2px solid rgba(255, 255, 255, .35); }
html[data-theme="light"] .hotel-hero { border-color: rgba(47, 107, 79, .45); }

/* ----------------------------------------------------------------------------
 * 9. Chips & badges
 * -------------------------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: var(--radius-pill);
  background: var(--tint-bg); color: var(--c-primary);
  font-size: 13px; font-weight: 600;
}
.chip i { font-size: 15px; }
/* solid filled chip — white text on the active colour; high contrast in both modes */
.chip--solid { background: var(--c-primary); color: #fff; }
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 600;
  background: var(--surface-2); color: var(--ink-soft); border: 1px solid var(--line);
}
.badge--accent { background: var(--c-accent); color: var(--on-accent); border-color: transparent; }
.price { font-weight: 600; }
.price small { color: var(--muted); font-weight: 400; }

/* ----------------------------------------------------------------------------
 * 10. Forms
 * -------------------------------------------------------------------------- */
.field { display: grid; gap: 6px; }
.field > label { font-weight: 600; font-size: 14px; }
.input, .select, .textarea, select.input {
  width: 100%; min-height: 48px; padding: 12px 14px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.textarea { min-height: 96px; resize: vertical; }
select.input { height: 51px; } /* match the rendered text-input height (e.g. Offerte: Tipo = Titolo) */
.input::placeholder, .textarea::placeholder { color: var(--muted); opacity: .6; }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--c-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-primary) 22%, transparent);
}
.field__hint { font-size: 13px; color: var(--muted); }
.field--error .input, .field--error .select, .field--error .textarea { border-color: var(--danger); }
/* The read-only account line in "Cambia password" — it exists so iOS/Safari can file the new
   password against the right login. Present and readable, but plainly not something you fill in. */
.input--acct { opacity: .6; pointer-events: none; }
.field__error { font-size: 13px; color: var(--danger); font-weight: 600; }

.check { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.check input { width: 20px; height: 20px; margin-top: 1px; accent-color: var(--c-primary); flex: none; }

/* ----------------------------------------------------------------------------
 * 11. App header (sticky) + horizon seam
 * -------------------------------------------------------------------------- */
.appbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 8px;
  padding: 10px 8px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
}
.appbar__title { font-family: var(--font-display); font-weight: 600; font-size: 17px; flex: 1; text-align: center; }
.appbar__title--left { text-align: left; padding-left: 4px; }

/* ----------------------------------------------------------------------------
 * 12. Bottom tab bar (guest zone)
 * -------------------------------------------------------------------------- */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  display: flex; gap: 2px;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
}
.tab {
  position: relative;
  flex: 1; display: grid; justify-items: center; gap: 3px;
  padding: 8px 4px; border-radius: var(--radius-sm);
  color: var(--muted); text-decoration: none; font-size: 11px; font-weight: 600;
}
.tab:hover { text-decoration: none; color: var(--ink); }
.tab i { font-size: 23px; }
.tab.is-active { color: var(--c-primary); }
/* "novità" dot on the Speciali tab — new specials the customer hasn't opened yet */
.tab-badge { position: absolute; top: 4px; left: 50%; margin-left: 5px; width: 11px; height: 11px;
  border-radius: 999px; background: var(--c-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--surface) 92%, transparent); }

/* ----------------------------------------------------------------------------
 * 13. Empty state
 * -------------------------------------------------------------------------- */
.empty { text-align: center; padding: 40px 20px; color: var(--muted); }
.empty i { font-size: 32px; color: var(--line-strong); }
.empty__title { font-family: var(--font-display); font-weight: 600; font-size: 17px; color: var(--ink); margin: 10px 0 4px; }

/* ----------------------------------------------------------------------------
 * App footer — shared by the customer app + the Manager. Sits as the last child
 * of the page's content container (.container / .container--wide, both padded by
 * --space); the negative inline margin bleeds the hairline out to those edges
 * (= edge-to-edge on the phone). Two small centred lines: legal links + credits.
 * -------------------------------------------------------------------------- */
.app-footer {
  margin: 30px calc(var(--space) * -1) 0;
  padding: 15px var(--space) 12px;
  border-top: 1px solid var(--line);
  text-align: center; color: var(--muted);
  font-family: var(--font-ui); font-size: 11.5px; line-height: 1.5;
}
.app-footer__row { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 7px; margin: 0; }
.app-footer__credits { margin-top: 5px; }
/* the Telaio lockup under the credits — quiet brand sign-off, links to the product page */
.app-footer__brand { display: block; width: 92px; margin: 16px auto 0; color: var(--ink); opacity: .55; transition: opacity .15s ease; }
.app-footer__brand:hover, .app-footer__brand:active { opacity: .9; }
.app-footer__brand svg { display: block; width: 100%; height: auto; }
.app-footer__sep { color: var(--line-strong); }
.app-footer__link { color: var(--muted); text-decoration: none; background: none; border: 0; padding: 0; font: inherit; cursor: pointer; }
.app-footer__link:hover { color: var(--ink); text-decoration: underline; }
.app-footer__ver { color: var(--muted); opacity: .75; font-variant-numeric: tabular-nums; }

/* ----------------------------------------------------------------------------
 * 14. Toast (created by core/ui.js)
 * -------------------------------------------------------------------------- */
#fh-toasts {
  position: fixed; left: 0; right: 0; bottom: calc(16px + env(safe-area-inset-bottom));
  display: grid; justify-items: center; gap: 8px; pointer-events: none;
  /* ⚠️ ABOVE EVERY OVERLAY. This was 60 — under .cardmodal (85), .cropper (100), .ferie-modal (150)
     and .hq-modal (1000) — so any message raised while a dialog was open rendered BEHIND it and the
     owner saw nothing (found on Tony's iPhone: "le due password non coincidono" was painting under
     the Cambia-password modal). A toast is the answer to something you just did; it must outrank
     whatever you did it in. Only the rotate guard (9999) sits higher — by design, nothing should
     draw over "turn your phone upright". */
  z-index: 9500;
}
.toast {
  background: var(--c-primary-dark); color: #fff;
  padding: 11px 18px; border-radius: var(--radius-pill); font-size: 14px; font-weight: 600;
  box-shadow: var(--shadow-md); max-width: calc(var(--maxw) - 32px);
  opacity: 0; transform: translateY(8px); transition: opacity .2s ease, transform .2s ease;
}
.toast.is-visible { opacity: 1; transform: none; }
.toast--success { background: var(--success); }
.toast--error { background: var(--danger); }

/* ----------------------------------------------------------------------------
 * 15. App structure components (Tasks 7–17)
 * -------------------------------------------------------------------------- */
/* website section menu (overlay sheet) */
.sheet { position: fixed; inset: 0; z-index: 40; display: flex; justify-content: flex-end; }
.sheet[hidden] { display: none; }
.sheet__backdrop { position: absolute; inset: 0; background: rgba(8, 16, 20, .45); }
.sheet__panel { position: relative; width: min(320px, 84vw); height: 100%;
  padding: calc(env(safe-area-inset-top) + 14px) 16px calc(env(safe-area-inset-bottom) + 16px) 16px;
  background: var(--surface); box-shadow: var(--shadow-md); display: flex; flex-direction: column; gap: 8px; overflow-y: auto; }
.sheet__head { display: flex; align-items: center; justify-content: space-between; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.sheet__nav { display: flex; flex-direction: column; }
.sheet__link { display: block; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--line);
  padding: 14px 6px; font: inherit; color: var(--ink); cursor: pointer; text-decoration: none; }
.sheet__link:hover { color: var(--c-primary); text-decoration: none; }

/* "GUEST PRIVATE AREA" — full-width footer bar pinned to the bottom; the page
   content scrolls underneath it. Accent colour, centred text. */
.appbanner-wrap { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; }
.appbanner { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  width: 100%; padding: 12px 18px calc(12px + env(safe-area-inset-bottom));
  color: var(--on-accent); text-align: center; text-decoration: none;
  background: linear-gradient(180deg, color-mix(in srgb, #fff 16%, var(--c-accent)) 0%, var(--c-accent) 72%, color-mix(in srgb, var(--c-accent) 86%, #000) 100%);
  border-top: 1px solid color-mix(in srgb, #000 24%, var(--c-accent)); box-shadow: 0 -6px 18px rgba(8, 16, 20, .20); }
.appbanner:hover { text-decoration: none; filter: brightness(1.03); }
.appbanner:active { filter: brightness(.985); }
.appbanner__text { display: flex; flex-direction: column; align-items: center; line-height: 1.25; min-width: 0; }
.appbanner__text strong { font-size: 19.5px; letter-spacing: .06em; font-weight: 800; }
.appbanner__text small { opacity: .85; font-size: 13px; }

/* hotel-page badge chip — brighter, higher-contrast text so it reads clearly */
.app--hotel .chip { color: var(--ink); }

/* tab bar: a divider before the Settings tab */
.tab-sep { flex: none; align-self: center; width: 1px; height: 26px; margin: 0 3px; background: var(--line-strong); }

/* segmented control (Settings → Appearance) */
.seg-group { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 4px; }
.seg-group--2 { grid-template-columns: repeat(2, 1fr); } /* exact 50/50 split (e.g. Orari: Generale | Singole giornate) */
.seg-group--4 { grid-template-columns: repeat(4, 1fr); } /* Archivio: Piatti · Drink · Eventi · Menu all on one row */
.seg-group--4 .seg { padding: 10px 2px; font-size: 12.5px; }
.seg { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 10px 6px;
  border: 0; background: transparent; color: var(--muted); font: inherit; font-weight: 600; font-size: 13px;
  border-radius: var(--radius-sm); cursor: pointer; }
.seg.is-active { background: var(--surface); color: var(--c-primary); box-shadow: var(--shadow-sm); }
.seg i { font-size: 16px; }

/* toggle switch (Settings) */
.switch { flex: none; width: 46px; height: 28px; border-radius: var(--radius-pill);
  background: var(--line-strong); position: relative; cursor: pointer; transition: background-color .18s ease; }
.switch.is-on { background: var(--c-primary); }
.switch__dot { position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .3); transition: transform .18s ease; }
.switch.is-on .switch__dot { transform: translateX(18px); }

/* A CHECKMARK, not a switch — used only for "Mostra in Home" under the Menu Fisso formulas.
   Those formulas each carry a real switch, and a fourth identical switch directly beneath them read
   as a third formula (Tony, 2026-07-21). A different control says "this is a different KIND of
   thing" without a word of explanation. */
.chkbox { flex: none; width: 28px; height: 28px; border-radius: 9px; padding: 0; cursor: pointer;
  display: grid; place-items: center; background: transparent; color: transparent;
  border: 1.5px solid var(--line-strong); transition: background-color .15s ease, border-color .15s ease; }
.chkbox.is-on { background: var(--c-primary); border-color: var(--c-primary); color: var(--on-primary, #fff); }
.chkbox.is-disabled { opacity: .4; pointer-events: none; }   /* the Home cap is reached — same read as the old switch */

/* dashboard quick tiles + hotel services grid */
.tiles, .svc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.tile { display: grid; justify-items: center; gap: 6px; text-align: center; padding: 14px 8px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink); text-decoration: none; font-weight: 600; }
.tile:hover { border-color: var(--line-strong); text-decoration: none; }
.svc { display: grid; justify-items: center; gap: 6px; text-align: center; }

/* gallery — each cell is a button that opens the photo full-screen */
.g-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.g-cell { padding: 0; border: 0; background: none; cursor: zoom-in; border-radius: var(--radius-sm); overflow: hidden; display: block; }
.g-cell:hover .g-img { transform: scale(1.04); filter: brightness(1.03); }
.g-img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-sm); transition: transform .3s ease, filter .3s ease; }

/* "Il locale" gallery — a big hero photo + a thumbnail selector: tap a thumb to swap the hero (no modal) */
.loc-gallery { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.loc-gallery__hero { position: relative; width: 100%; aspect-ratio: 16 / 10; border-radius: var(--radius-card); overflow: hidden; background: #0c0c0c; cursor: zoom-in; }
.loc-gallery__blur { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transform: scale(1.15); filter: blur(20px) brightness(.68) saturate(1.1); } /* fills the frame so there are no empty bars */
.loc-gallery__main { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; } /* the whole photo, sharp, uncropped */
.loc-gallery__expand { position: absolute; right: 8px; bottom: 8px; width: 30px; height: 30px; display: grid; place-items: center; border-radius: 999px; background: rgba(0, 0, 0, .5); color: #fff; -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); pointer-events: none; }
.loc-gallery__expand i { display: flex; align-items: center; justify-content: center; }
/* min-width:0 + overflow lets the strip scroll INSIDE the app width instead of forcing the page wider */
.loc-gallery__thumbs { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding: 2px; margin: -2px; min-width: 0; max-width: 100%; }
.loc-gallery__thumbs::-webkit-scrollbar { display: none; }
.loc-gallery__thumb { flex: 0 0 auto; width: 64px; height: 64px; border-radius: var(--radius-sm); overflow: hidden; padding: 0; border: 2px solid transparent; background: var(--tint-bg); cursor: pointer; opacity: .55; transition: opacity .15s ease, border-color .15s ease; }
.loc-gallery__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.loc-gallery__thumb:hover { opacity: 1; }
.loc-gallery__thumb.is-active { opacity: 1; border-color: var(--c-primary); }

/* full-screen photo lightbox / carousel (created by app.js; swipe, arrows, ← → keys, Esc) */
.lightbox { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center;
  background: rgba(8, 12, 14, .92); padding: 16px; cursor: zoom-out; animation: lb-fade .15s ease; }
.lightbox__img { max-width: 100%; max-height: 100%; width: auto; height: auto; cursor: default;
  border-radius: var(--radius-sm); box-shadow: 0 24px 70px rgba(0, 0, 0, .6); }
/* bare glyphs, no circles (Tony 2026-07-15) — a drop-shadow keeps them readable over bright photos */
.lightbox__btn { position: absolute; z-index: 1; display: grid; place-items: center; cursor: pointer; color: #fff;
  background: none; border: 0; filter: drop-shadow(0 1px 5px rgba(0, 0, 0, .65)); transition: opacity .15s ease, transform .06s ease; }
.lightbox__btn i { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; line-height: 1; }
.lightbox__btn[hidden] { display: none; }   /* single-photo gallery: display:grid would defeat the hidden attribute → ghost arrows that "do nothing" */
.lightbox__btn:hover { opacity: .8; }
.lightbox__btn:active { transform: scale(.92); }
.lightbox__close { top: max(14px, env(safe-area-inset-top)); right: 14px; width: 42px; height: 42px; }
.lightbox__nav { top: 50%; transform: translateY(-50%); width: 48px; height: 48px; }
.lightbox__nav--prev { left: 12px; }
.lightbox__nav--next { right: 12px; }
.lightbox__nav:active { transform: translateY(-50%) scale(.92); }
.lightbox__count { position: absolute; left: 0; right: 0; bottom: max(16px, env(safe-area-inset-bottom)); text-align: center;
  color: rgba(255, 255, 255, .85); font: 600 14px var(--font-ui); letter-spacing: .05em; }
@keyframes lb-fade { from { opacity: 0; } to { opacity: 1; } }

/* "Add to Home Screen" — a bottom sheet that collapses to an always-visible PEEK
   bar you can tap to reopen (installPrompt.js). Inverted vs the theme so it stays
   visible: cream over the dark app, dark over the light app. */
.installsheet { position: fixed; inset: 0; z-index: 90; display: flex; align-items: flex-end; pointer-events: none; }
.installsheet__backdrop { position: absolute; inset: 0; background: rgba(8, 12, 14, .5); opacity: 0; transition: opacity .34s ease; pointer-events: none; }
.installsheet.is-in:not(.is-offroute):not(.is-collapsed) .installsheet__backdrop { opacity: 1; pointer-events: auto; }
.installsheet__panel { position: relative; width: 100%; max-width: 540px; margin-inline: auto; pointer-events: auto;
  border-radius: 22px 22px 0 0; box-shadow: 0 -22px 60px rgba(0, 0, 0, .42);
  padding: 0 22px env(safe-area-inset-bottom);
  transform: translateY(102%); transition: transform .42s cubic-bezier(.22, 1, .36, 1), margin-bottom .28s ease; }
.installsheet.is-in:not(.is-offroute) .installsheet__panel { transform: translateY(0); }
.installsheet.is-collapsed .installsheet__panel { margin-bottom: var(--peek-offset, 0); } /* peek sits above the tab bar / footer banner */
html[data-theme="dark"] .installsheet__panel { background: #f6f3ec; color: #15211c; }
html[data-theme="light"] .installsheet__panel { background: #1b211e; color: #f3f1ea; }

.ish__bar { display: flex; align-items: center; gap: 13px; width: 100%; padding: 12px 0; background: none; border: 0; cursor: pointer; text-align: left; color: inherit; font: inherit; }
.ish__icon { flex: none; border-radius: 10px; }
html[data-theme="dark"] .ish__icon { box-shadow: 0 0 0 1px rgba(21, 33, 28, .12); }
html[data-theme="light"] .ish__icon { box-shadow: 0 2px 10px rgba(0, 0, 0, .3); }
.ish__bartext { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ish__eyebrow { font-family: var(--font-ui); font-size: 11.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; opacity: .5; }
.ish__title { font-family: var(--font-ui); font-weight: 800; font-size: 18px; line-height: 1.15; }
.ish__chev { flex: none; width: 22px; height: 22px; opacity: .45; transition: transform .3s ease; }
.installsheet:not(.is-collapsed) .ish__chev { transform: rotate(180deg); }

.ish__body { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .36s cubic-bezier(.22, 1, .36, 1); }
.installsheet.is-collapsed .ish__body { grid-template-rows: 0fr; }
.ish__body-inner { overflow: hidden; min-height: 0; }
.ish__body-inner--centered { text-align: center; }
.ish__body-inner--centered .ish__steps { text-align: left; }
.ish__biglogo { display: block; margin: 6px auto 12px; width: 94px; height: 94px; border-radius: 21px; box-shadow: 0 12px 30px rgba(0,0,0,.16); }
.ish__bigtitle { margin: 0 0 6px; font-size: 19px; font-weight: 800; letter-spacing: .03em; text-transform: uppercase; color: inherit; }
.ish__add { margin: 8px 0 0; }
.ish__lead { margin: 0; opacity: .62; font-size: 14.5px; line-height: 1.4; }
.ish__steps { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.ish__step { display: flex; align-items: flex-start; gap: 13px; }
.ish__num { flex: none; width: 28px; height: 28px; border-radius: 50%; border: 2px solid; display: grid; place-items: center;
  font-family: var(--font-ui); font-weight: 700; font-size: 14px; margin-top: 1px; }
html[data-theme="dark"] .ish__num, html[data-theme="dark"] .ish__share { color: #2f6b4f; }
html[data-theme="light"] .ish__num, html[data-theme="light"] .ish__share { color: #6aa886; }
.ish__step p { margin: 0; font-size: 15.5px; line-height: 1.45; }
.ish__hint { opacity: .6; font-weight: 400; }
.ish__share { display: inline-block; width: 17px; height: 17px; vertical-align: -3px; margin: 0 1px; }
.ish__install { display: block; width: 100%; margin: 14px 0 2px; min-height: 50px; font-weight: 700; letter-spacing: .02em; }
.ish__rule { height: 1px; border: 0; background: currentColor; opacity: .14; margin: 20px 0 0; }
.ish__or { text-align: center; opacity: .55; font-size: 13px; margin: 16px 0 10px; }
.ish__browser { display: block; width: 100%; padding: 13px; border-radius: var(--radius); font: inherit; font-weight: 700;
  cursor: pointer; background: transparent; color: inherit; border: 1.5px solid currentColor; transition: background-color .15s ease; }
.ish__browser:hover { background: color-mix(in srgb, currentColor 12%, transparent); }
.ish__note { text-align: center; opacity: .5; font-size: 12px; line-height: 1.4; margin: 10px 4px 18px; }

/* unlock screen — bigger, full-strength lead (not muted grey) */
.unlock-lead { font-size: 16px; line-height: 1.5; color: var(--ink); margin: 0; }

/* loyalty — three colour-graded "earn points" actions (value → colour) */
.earn-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.earn-btn { display: grid; gap: 5px; justify-items: center; text-align: center;
  padding: 14px 8px; border-radius: var(--radius); border: 1px solid transparent;
  background: var(--surface); color: var(--ink); cursor: pointer; font: inherit;
  transition: filter .15s ease, transform .06s ease; }
.earn-btn:hover { filter: brightness(1.04); }
.earn-btn:active { transform: translateY(1px); }
.earn-btn__pts { font-family: var(--font-display); font-weight: 600; font-size: 22px; line-height: 1; }
.earn-btn__cap { font-size: 11px; line-height: 1.25; color: var(--muted); }
.earn-btn--s { background: color-mix(in srgb, #3b82f6 14%, var(--surface)); border-color: color-mix(in srgb, #3b82f6 30%, transparent); }
.earn-btn--s .earn-btn__pts { color: #3b82f6; }
.earn-btn--m { background: color-mix(in srgb, var(--c-accent) 18%, var(--surface)); border-color: color-mix(in srgb, var(--c-accent) 38%, transparent); }
.earn-btn--m .earn-btn__pts { color: color-mix(in srgb, var(--c-accent) 78%, var(--ink)); }
.earn-btn--l { background: color-mix(in srgb, var(--success) 16%, var(--surface)); border-color: color-mix(in srgb, var(--success) 36%, transparent); }
.earn-btn--l .earn-btn__pts { color: var(--success); }

/* current membership level highlight (wallet) */
.row--current { border-color: color-mix(in srgb, var(--c-accent) 55%, transparent); background: color-mix(in srgb, var(--c-accent) 9%, var(--surface)); }

/* beach spot picker */
.beach-grid { display: grid; gap: 6px; margin-top: 12px; }
.spot { aspect-ratio: 1; border: 1px solid var(--line-strong); border-radius: 6px; background: var(--surface);
  color: var(--muted); font-size: 11px; font-weight: 600; cursor: pointer; }
.spot:hover:not(:disabled) { border-color: var(--c-primary); color: var(--c-primary); }
.spot.is-taken { background: var(--surface-2); color: var(--line-strong); cursor: not-allowed; }
.spot.is-sel { background: var(--c-primary); color: #fff; border-color: var(--c-primary); }
.legend { display: inline-block; width: 12px; height: 12px; border-radius: 3px; vertical-align: -1px; border: 1px solid var(--line-strong); }
.legend--free { background: var(--surface); }
.legend--taken { background: var(--surface-2); }
.legend--sel { background: var(--c-primary); border-color: var(--c-primary); }

/* ----------------------------------------------------------------------------
 * 16. Motion preferences
 * -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .hotel-card:hover > img { transform: none; }
}

/* ── Super-admin — full-page control room ──────────────────────────────────── */
.container--wide { width: 100%; max-width: 1080px; margin-inline: auto; padding-inline: var(--space); }
.admin-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: start; }
@media (max-width: 760px) { .admin-cols { grid-template-columns: 1fr; } }
.su-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 16px; align-items: start; }
.su-card { display: flex; flex-direction: column; gap: 12px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface);
  padding: 16px; box-shadow: 0 1px 3px rgba(20, 33, 28, .05); }
.su-card__head { display: flex; gap: 12px; align-items: center; }
/* The size lives HERE, not on the tag: the preset cards pass width/height attributes on an <img>, but
   a wizard client's face is a <span> wrapping its logo — with no size on the class, its inner "82%"
   had nothing to resolve against and the logo rendered at natural size, blowing the card apart. */
.su-card__icon { width: 46px; height: 46px; border-radius: 11px; border: 1px solid var(--line); flex: none; }
.su-card__name { font-weight: 700; display: block; line-height: 1.2; }
.su-card__vert { color: var(--muted); font-size: 12.5px; text-transform: capitalize; }
.su-card__mods { display: flex; flex-wrap: wrap; gap: 6px; }
.su-swatch { display: inline-block; width: 13px; height: 13px; border-radius: 4px; border: 1px solid rgba(0, 0, 0, .15); vertical-align: middle; }
.chip--xs { font-size: 11px; padding: 3px 9px; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--muted); text-transform: none; }
.su-edit { border-top: 1px solid var(--line); padding-top: 12px; }
.su-field { display: flex; flex-direction: column; gap: 5px; }
.su-field > label { font-size: 12.5px; color: var(--muted); }
.su-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.su-edit input[type="color"] { width: 46px; height: 40px; padding: 2px; border: 1px solid var(--line); border-radius: 9px; background: var(--surface); cursor: pointer; }
.su-logo { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px; border: 1px dashed var(--line); border-radius: 12px; }
.su-logo.is-drop { border-color: var(--c-primary); border-style: solid; }
.su-logo__prev { height: 44px; max-width: 180px; object-fit: contain; }
@media (max-width: 480px) { .su-2col { grid-template-columns: 1fr; } }

/* ── Public (walk-in) app — Osteria / Bar / Tenuta ─────────────────────────── */
.menus-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.menus-2--single { grid-template-columns: 1fr; } /* one active formula → full width */
/* Every Menu Fisso card is a container so its contents scale WITH the card (which scales with the
   screen) — no overflow / off-centre on small phones, in any style. */
.setmenu { text-align: center; padding: 4px 2px; container-type: inline-size; min-width: 0; }
.setmenu--link { cursor: pointer; }
/* Force a simple centred flex column (the shared .stack is a grid, whose auto column drifts with the
   widest item). Now chip + price shrink-to-fit and centre; the description spans full width so its
   wrapped lines centre too. Nothing can drift off-centre regardless of price/name length. */
.setmenu .card__body { display: flex; flex-direction: column; align-items: center; }
.setmenu .card__body > * { max-width: 100%; }
.setmenu .card__body > .muted { align-self: stretch; }
.setmenu__name { font-weight: 700; font-size: clamp(13px, 12cqi, 16.5px); }
.setmenu__price { font-size: clamp(23px, 22cqi, 32px); font-weight: 800; color: var(--c-primary); line-height: 1.05; max-width: 100%; }
.dispo { display: flex; justify-content: space-between; align-items: center; padding: 9px 0; border-top: 1px solid var(--line); }
.dispo:first-child { border-top: 0; }
.dispo__turno { font-weight: 600; font-size: 15px; }
.dispo__posti { font-weight: 700; color: var(--c-primary); }
.dispo__posti.is-full { color: var(--muted); }

/* multi-day availability (TRACK M) — date header + tappable day chips (horizontal scroll) */
.day-head { font-size: 13.5px; font-weight: 700; color: var(--muted); letter-spacing: .01em; text-transform: capitalize; margin-top: -2px; }
/* "Orari e Disponibilità" (customer): a standalone card that INVERTS the theme so it stands out —
   light card in dark mode, dark card in light mode. Flipping the tokens flips every child with it. */
.dispo-panel { background: var(--surface); color: var(--ink); }
:root[data-theme="dark"] .dispo-panel { --surface: #f3ebd9; --surface-2: #eae1cb; --ink: #15211c; --muted: #6b6f6a; --line: rgba(0, 0, 0, .10); --line-strong: rgba(38, 32, 18, .22); }
:root[data-theme="light"] .dispo-panel { --surface: #242c33; --surface-2: #2c343d; --ink: #eef1ea; --muted: #9aa49d; --line: rgba(255, 255, 255, .12); --line-strong: rgba(255, 255, 255, .24); }
.dispo-panel__ico { display: inline-flex; align-items: center; color: var(--c-primary); }
.dispo-panel__sep { height: 1px; border: 0; margin: 0; background: var(--line-strong); }
.day-chips { display: flex; gap: 7px; overflow-x: auto; scrollbar-width: none; margin: 0 -2px; padding: 2px; }
.day-chips::-webkit-scrollbar { display: none; }
.day-chip { flex: 0 0 auto; padding: 6px 12px; border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--muted);
  font-family: var(--font-ui); font-size: 12.5px; font-weight: 600; white-space: nowrap;
  transition: background .12s ease, color .12s ease, border-color .12s ease; }
.day-chip:hover { color: var(--ink); }
.day-chip.is-active { background: var(--c-primary); border-color: var(--c-primary); color: #fff; }
/* a closed day reads in RED at a glance (no need to tap): red text + red border + red strike */
.day-chip.is-closed:not(.is-active) {
  color: var(--danger-solid);
  border-color: color-mix(in srgb, var(--danger-solid) 55%, transparent);
  text-decoration: line-through; text-decoration-thickness: 1.5px;
  text-decoration-color: var(--danger-solid);
}
/* selecting a closed day: fill it solid red with white text (not the accent) so it still reads "chiuso" */
.day-chip.is-active.is-closed { background: var(--danger-solid); border-color: var(--danger-solid); color: #fff; text-decoration: none; }
/* weekday multi-select (Manager → Chiusure e ferie → Chiusura settimanale) */
.day-pick { flex: 0 0 auto; min-width: 46px; padding: 7px 12px; border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--muted);
  font-family: var(--font-ui); font-size: 13px; font-weight: 600; text-align: center;
  transition: background .12s ease, color .12s ease, border-color .12s ease; }
.day-pick:hover { color: var(--ink); }
.day-pick.is-on { background: var(--c-primary); border-color: var(--c-primary); color: #fff; }
/* a borderless label+switch row that breathes (no box) — forms + settings panels */
.togglerow { display: flex; align-items: center; justify-content: space-between; gap: 14px; width: 100%; }
/* a soft inner panel (e.g. Chiusura settimanale / Ferie inside "Chiusure e ferie") */
.subpanel { border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--surface); padding: 15px 16px; }
/* one ferie period inside the Ferie subpanel */
.ferie-item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--ink) 5%, var(--surface)); }
.ferie-item .row__text { flex: 1; min-width: 0; }
/* closed-day body — a CENTERED red "Chiuso" badge + the closure message */
.dispo-closed { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 10px 0 4px; text-align: center; }
.dispo-closed__tag { display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 14px; border-radius: var(--radius-pill); font-size: 13.5px; font-weight: 700;
  background: color-mix(in srgb, var(--danger-solid) 14%, transparent);
  color: var(--danger-solid); }
.dispo-closed__tag i { color: var(--danger-solid); }
.dispo-closed__msg { margin: 0; font-size: 14px; line-height: 1.4; color: var(--muted); max-width: 36ch; }
/* Home ferie banner — unmissable when today is inside a holiday period */
.ferie-banner { display: flex; align-items: center; gap: 10px; margin-bottom: 18px;
  padding: 12px 15px; border-radius: var(--radius-card); font-size: 14px; font-weight: 600; line-height: 1.35;
  background: color-mix(in srgb, var(--c-accent) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--c-accent) 34%, transparent); color: var(--ink); }
.ferie-banner i { flex: none; color: var(--c-accent); }
/* "Chiuso per ferie" — a big centred card (same shape as the offer block), warm ferie colours. */
.ferie-card { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 5px; margin-bottom: 18px;
  padding: 20px 16px; border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--c-accent) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--c-accent) 34%, transparent); }
.ferie-card__icon { color: var(--c-accent); line-height: 1; }
.ferie-card__icon i { font-size: 36px; }
.ferie-card__title { font-weight: 800; font-size: 19px; letter-spacing: -.2px; color: var(--ink); }
.ferie-card__period { font-size: 14px; color: var(--muted); text-transform: capitalize; }
/* "Chiuso per ferie" pop-up — an on-open alert modal. Reuses the .cardmodal backdrop; lifted above every
   other overlay (install sheet 90, lightbox 80…) so a closure is the first thing seen. */
/* .cardmodal.ferie-modal (not just .ferie-modal) so these beat the shared .cardmodal rule regardless of
   source order. Darker backdrop than the default card modal — the app stays faintly visible behind, but
   the closure clearly takes over the screen. */
.cardmodal.ferie-modal { z-index: 150; background: rgba(0, 0, 0, .88); }
.ferie-modal__panel { width: min(360px, 100%); padding: 30px 24px calc(26px + env(safe-area-inset-bottom)); text-align: center; display: flex; flex-direction: column; align-items: center; gap: 8px; border: 1px solid rgba(255, 255, 255, .2); animation: feriePop .22s ease-out; }
.ferie-modal__icon { color: var(--c-accent); line-height: 1; }
.ferie-modal__icon i { font-size: 46px; }
.ferie-modal__title { margin: 8px 0 0; font-size: 22px; font-weight: 800; letter-spacing: -.2px; color: var(--ink); }
.ferie-modal__period { margin: 0; font-size: 15px; color: var(--muted); text-transform: capitalize; }
.ferie-modal__bye { margin: 6px 0 16px; font-size: 15px; color: var(--ink); }
@keyframes feriePop { from { opacity: 0; transform: translateY(12px) scale(.97); } to { opacity: 1; transform: none; } }
/* The header logo is an INLINE <svg> (see publicApp header + panevino-logo.js). Sized by WIDTH with
   height:auto from the viewBox → the box is reserved synchronously on first paint (no collapse-then-grow
   jump) and it never fetches (no flash / no broken-image "?"). --logo-scale is the Super-Admin size knob
   (65%×1.2 ≈ the approved 78% width). max-width caps it on the narrowest phones. */
.landing-head__logo { display: block; margin-inline: auto; width: calc(68% * var(--logo-scale, 1)); height: auto; max-width: 92%; }

/* restaurant admin — compact table inventory + tap-to-book tiles */
.tbl-inv-row { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.tbl-inv { display: flex; flex-direction: column; gap: 3px; }
.tbl-inv label { font-size: 11px; color: var(--muted); }
.tbl-inv .input { width: 52px; padding: 8px 6px; text-align: center; }
.tbl-inv-row .btn { min-height: 48px; } /* match the da-8/da-6 input height */
.tbl { min-width: 38px; height: 38px; padding: 0 9px; border-radius: 9px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); font-weight: 700; font-size: 16px; cursor: pointer; transition: transform .05s ease; }
.tbl:active { transform: scale(.93); }
.tbl.is-booked { background: #8a2024; border-color: #8a2024; color: #fff; position: relative; overflow: hidden; }
/* booked = crossed out (unavailable): a thin 1px diagonal line across the red tile */
.tbl.is-booked::after { content: ""; position: absolute; inset: 0; background:
  linear-gradient(to top right, transparent calc(50% - .5px), rgba(255, 255, 255, .92) calc(50% - .5px),
  rgba(255, 255, 255, .92) calc(50% + .5px), transparent calc(50% + .5px)); }

/* "add" zones in Gestione — a light dashed panel: heading, full-width fields, action on its own row */
.addzone { background: var(--tint-bg); border: 1px dashed color-mix(in srgb, var(--c-primary) 30%, var(--line)); border-radius: 12px; padding: 14px; }
.addzone__title { display: block; font-weight: 700; color: var(--c-primary); font-size: 12px; text-transform: uppercase; letter-spacing: .05em; margin-bottom: 10px; }
.addzone__fields { display: flex; flex-direction: column; gap: 10px; }
.addzone__row { display: flex; gap: 10px; align-items: flex-end; }
.addzone .su-field { width: 100%; }
.addzone .su-field .input, .addzone .su-field select.input { width: 100%; max-width: none; }
/* same-row action button matches the input height (so they line up) */
.addzone__row { align-items: stretch; }
.addzone__row .su-field { display: flex; flex-direction: column; }
.addzone__row .su-field .input-money, .addzone__row .su-field .input { margin-top: auto; }

/* per-field owner-content translation: the language chips + the "Traduci in …" modal */
.langchips { gap: 7px; }
.langchips__label { font-size: 12.5px; color: var(--muted); }
.langchips__row { display: flex; flex-wrap: wrap; gap: 6px; }
.langchip {
  position: relative; min-width: 38px; padding: 6px 9px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink);
  font-size: 12px; font-weight: 700; letter-spacing: .04em; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1;
}
.langchip:hover { border-color: var(--muted); }
.langchip--it { cursor: default; opacity: .85; }
.langchip.is-active { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.langchip__dot {
  position: absolute; top: -3px; right: -3px; width: 8px; height: 8px; border-radius: 50%;
  background: #2e9c5a; border: 1.5px solid var(--surface);
}
.langtr__orig {
  font-size: 13px; color: var(--muted); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 8px; padding: 7px 10px; min-height: 20px;
}
.langtr__g { align-self: flex-start; gap: 6px; }

/* titled field panel inside the Speciale form (Avvisa i clienti = switch reveals its body; Offerta = always open) */
.fpanel { border: 1px solid var(--line); border-radius: 12px; background: var(--surface-2); overflow: hidden; }
/* the flagship "Offerta per i clienti" panel: light gold border + a soft outer glow (Tony 2026-07-15) */
.fpanel--gold { border-color: color-mix(in srgb, #d9a23c 45%, var(--line)); box-shadow: 0 0 14px color-mix(in srgb, #d9a23c 16%, transparent); }
.fpanel__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 14px; }
.fpanel__title { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; color: var(--ink); }
.fpanel__note { font-size: 12.5px; font-weight: 600; color: var(--c-primary); }   /* Mostra in Home: the orange "Te ne rimangono N" notice */
.fpanel__body { padding: 0 14px 14px; display: flex; flex-direction: column; gap: 11px; }
/* the "how to write a good offer" tip inside the Offerta panel */
.fpanel__tip { display: flex; gap: 7px; align-items: flex-start; margin: 0; font-size: 12px; line-height: 1.45;
  color: color-mix(in srgb, var(--c-primary) 82%, var(--ink));
  background: color-mix(in srgb, var(--c-primary) 9%, var(--surface)); border-radius: 9px; padding: 9px 11px; }
.fpanel__tip i { flex: none; margin-top: 1px; font-size: 15px; color: var(--c-primary); }
.addzone__row .btn { align-self: flex-end; min-height: 51px; }
/* money field: "Costo" label, € shown inside the field */
.input-money { position: relative; }
.input-money__sym { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); color: var(--muted); pointer-events: none; line-height: 1; }
.input-money .input { padding-left: 28px; }
/* "Immagine" field in the add/edit modal: big preview + Carica / Cancella stacked beside it */
.imgfield { display: flex; gap: 12px; align-items: center; }
.imgfield__preview { width: 92px; height: 92px; border-radius: 12px; object-fit: cover; flex: 0 0 auto; background: var(--tint-bg); cursor: pointer; }
.imgfield__preview--empty { display: inline-flex; align-items: center; justify-content: center; color: var(--muted); }
.imgfield__preview--empty i { font-size: 30px; }
.imgfield__btns { display: flex; flex-direction: column; gap: 8px; min-width: 120px; }

/* image framing/crop modal (openImageCropper) — pick which part of the photo fills the card */
.cropper { position: fixed; inset: 0; z-index: 100; background: rgba(0, 0, 0, .72); display: grid; place-items: center; padding: 16px; }
.cropper__panel { background: var(--surface); border-radius: var(--radius-card); padding: 16px; width: min(440px, 94vw); max-height: 92vh; display: flex; flex-direction: column; gap: 12px; box-shadow: var(--shadow-md); }
.cropper__head { font-family: var(--font-display); font-weight: 600; font-size: 18px; }
.cropper__stage { position: relative; width: 100%; height: 56vh; max-height: 460px; background: #0c0c0c; border-radius: var(--radius-sm); overflow: hidden; touch-action: none; user-select: none; }
.cropper__img { position: absolute; user-select: none; -webkit-user-drag: none; pointer-events: none;
  /* Checkerboard under the image (design-tool standard): a transparent/dark file was invisible
     against the dark stage, so the crop box seemed "stuck" when it had simply reached the
     image's real edge. Now the file's true bounds are always visible. */
  background: repeating-conic-gradient(#2e2e2e 0% 25%, #232323 0% 50%) 0 0 / 18px 18px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .18); }
.cropper__box { position: absolute; box-shadow: 0 0 0 9999px rgba(0, 0, 0, .5); border: 2px solid #fff; cursor: move; touch-action: none; }
.cropper__grip { position: absolute; right: -12px; bottom: -12px; width: 24px; height: 24px; border-radius: 999px; background: #fff; border: 2px solid var(--c-primary); cursor: nwse-resize; touch-action: none; box-shadow: 0 1px 4px rgba(0, 0, 0, .4); }
/* Thumb-sized invisible hit area (Apple minimum 44px): missing the 24px dot by a hair used to
   MOVE the box instead of resizing — which read as "the crop can only shrink" on the phone. */
.cropper__grip::after { content: ''; position: absolute; inset: -18px; border-radius: 999px; }
/* The second handle, freeform only (logos): top-left, so the two corners between them reach all
   four edges. Identical size/target to the first — nothing here should feel like the lesser grip. */
.cropper__grip--nw { right: auto; bottom: auto; left: -12px; top: -12px; }
.cropper__hint { margin: 0; font-size: 12.5px; color: var(--muted); text-align: center; }
.cropper__btns { display: flex; gap: 10px; }
.cropper__btns .btn { flex: 1; }

/* swipe-to-reveal rows (menu dishes): drag left → Archivia / Elimina (desktop: hover reveals) */
.swipe { position: relative; overflow: hidden; border-radius: var(--radius); }
.swipe__actions { position: absolute; top: 0; right: 0; bottom: 0; display: flex; }
.swipe__act { width: 84px; border: 0; color: #fff; font-weight: 700; font-size: 12px; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; }
.swipe__act i { font-size: 19px; }
.swipe__act--archive { background: #b4730b; }
.swipe__act--delete { background: var(--danger-solid); }
.swipe__content { position: relative; transition: transform .22s ease; will-change: transform; touch-action: pan-y; }
.swipe.is-open .swipe__content { transform: translateX(-168px); }
@media (hover: hover) { .swipe:hover .swipe__content { transform: translateX(-168px); } }

/* owner content thumbnails (resized photos on specialità / dishes / offers) */
.ra-thumb { width: 46px; height: 46px; border-radius: 9px; object-fit: cover; flex: 0 0 auto; background: var(--tint-bg); border: 1px solid var(--line); }
.ra-thumb--empty { display: inline-flex; align-items: center; justify-content: center; color: var(--muted); }
.ra-thumb--empty i { font-size: 20px; }

/* Photo reveal: content photos start hidden over a soft neutral placeholder and are shown by JS only
   once decoded (revealPhoto). Cached photos show instantly (no flash on repeat navigation); uncached
   ones fade in gently instead of hard-popping. */
img.notepad__thumb, img.offer-card__img, img.spec-card__img, img.pub-thumb {
  opacity: 0;
  background-color: color-mix(in srgb, var(--ink) 8%, var(--surface));
}
img.notepad__thumb.fade, img.offer-card__img.fade, img.spec-card__img.fade, img.pub-thumb.fade { transition: opacity .35s ease; }
img.notepad__thumb.is-ready, img.offer-card__img.is-ready, img.spec-card__img.is-ready, img.pub-thumb.is-ready { opacity: 1; }

/* "Il locale" gallery editor (Impostazioni App) — thumbnails with a remove button + an add tile */
.ra-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 8px; }
.ra-gallery__cell { position: relative; aspect-ratio: 1; border-radius: 9px; overflow: hidden; border: 1px solid var(--line); background: var(--tint-bg); }
.ra-gallery__cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ra-gallery__rm { position: absolute; top: 4px; right: 4px; width: 22px; height: 22px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 999px; background: rgba(0, 0, 0, .6); color: #fff; cursor: pointer; }
.ra-gallery__rm:hover { background: #c0322b; }
.ra-gallery__add { aspect-ratio: 1; display: grid; place-items: center; align-content: center; gap: 2px; border: 1.5px dashed var(--line-strong); border-radius: 9px; color: var(--muted); cursor: pointer; font-size: 12px; font-weight: 600; text-align: center; }
.ra-gallery__add:hover { border-color: var(--c-primary); color: var(--c-primary); }

/* the thumbnail itself is the upload/replace button in Gestione */
.ra-thumb-btn { display: inline-flex; padding: 0; border: 0; background: none; cursor: pointer; flex: 0 0 auto; -webkit-tap-highlight-color: transparent; }
.ra-thumb-btn .ra-thumb { transition: filter .15s ease; }
@media (hover: hover) { .ra-thumb-btn:hover .ra-thumb { filter: brightness(.88); } }

/* item ② — customer-facing photo thumbnails + tap-to-open card */
.pub-thumb { width: 54px; height: 54px; border-radius: 10px; object-fit: cover; flex: 0 0 auto; background: var(--tint-bg); border: 1px solid color-mix(in srgb, var(--c-primary) 35%, transparent); }
.pub-item { cursor: pointer; transition: transform .06s ease; }
.pub-item:active { transform: scale(.99); }
img.offer-card__img { object-fit: cover; }
.notepad__cam { color: var(--c-primary); opacity: .75; vertical-align: middle; }
/* notepad dish with a photo: small thumb on the left, as tall as the dish's rows */
.notepad__dish--photo { display: flex; gap: 10px; align-items: center; }
.notepad__dish--photo .notepad__dish-main { flex: 1 1 auto; min-width: 0; }
.notepad__thumb { width: 46px; height: 46px; flex: 0 0 auto; object-fit: cover; border-radius: 8px; background: var(--tint-bg); border: 1px solid color-mix(in srgb, var(--c-primary) 35%, transparent); }

/* the tap-to-open content card (built in app.js openCard) */
/* safe-area breathing room top & bottom so the modal never tucks under the notch / home bar (Tony 2026-07-18) */
.cardmodal { position: fixed; inset: 0; z-index: 85; display: grid; place-items: center;
  padding: calc(env(safe-area-inset-top) + 16px) 16px calc(env(safe-area-inset-bottom) + 16px);
  background: rgba(0, 0, 0, .9); }
.cardmodal__panel { position: relative; width: min(420px, 100%); max-height: 88vh; max-height: 88svh; overflow: auto; overscroll-behavior: contain;
  background: var(--surface); color: var(--ink); border-radius: 18px; box-shadow: 0 20px 60px rgba(0, 0, 0, .45);
  border: 1px solid color-mix(in srgb, var(--tipo, var(--c-primary)) 30%, var(--line)); }  /* the same light edge as the offer cards */
/* edit / editor modals: fixed × header + fixed footer, only the middle scrolls — the action buttons stay
   put (no scrolling to find them) AND this dodges the iOS repaint bug where the bottom of a long scroll
   sometimes wouldn't paint until you nudged it. */
/* max-height in svh (small-viewport) not %/vh/dvh — on iOS %/vh size to the LAYOUT viewport (behind the
   toolbar/home-indicator) pushing the footer off-screen, and dvh RESIZES live as browser chrome moves →
   the footer visibly jumps mid-gesture. svh = the smallest visible viewport: stable, footer always on
   screen. NOTE: NO -webkit-overflow-scrolling:touch on the body scroller — that legacy property has
   documented WebKit bugs (content inside fails to paint / stops scrolling after a resize, breaks fixed
   descendants); modern iOS momentum-scrolls natively without it. */
.cardmodal--form .cardmodal__panel, .cardmodal--editor .cardmodal__panel { display: flex; flex-direction: column; max-height: 88vh; max-height: 88svh; overflow: hidden; width: min(600px, 100%); }  /* wider on tablet so the editors match the Manager's own width — not a skinny 420 strip */
.cardmodal--form .cardmodal__body, .cardmodal--editor .cardmodal__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.cardmodal__footer { flex: none; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 12px 16px 14px; border-top: 1px solid var(--line); background: var(--surface); box-shadow: 0 -7px 18px rgba(0, 0, 0, .3); z-index: 1; }
.cardmodal__footer .btn { width: 100%; margin: 0; min-height: 46px; font-size: 14px; padding: 0 8px; gap: 6px; }
.cardmodal__footer .btn i { font-size: 16px; }
/* show the FULL photo (the owner's crop), never a re-cropped slice: the wrap sizes to the image,
   which is shown at its natural aspect ratio, bounded to the modal width and a sensible max height. */
.cardmodal__imgwrap { width: 100%; background: #0c0c0c; overflow: hidden; border-radius: 18px 18px 0 0; display: grid; place-items: center; }
.cardmodal__img { max-width: 100%; max-height: 62vh; object-fit: contain; display: block; }
.cardmodal__body { padding: 16px 18px 20px; }
/* The ✕ is absolutely placed top-right (40px box, 8px inset → it owns the first 48px). Text that starts at
   the very top of a modal must wrap BEFORE it, or the first line runs under the button (Tony spotted it on
   the "Esci" confirm). Only a leading heading/paragraph is nudged — images and forms keep the full width. */
.cardmodal__body > p:first-child,
.cardmodal__body > h3:first-child { padding-right: 36px; }
.cardmodal__top { display: flex; gap: 12px; justify-content: space-between; align-items: baseline; }
.cardmodal__name { margin: 0; font-size: 20px; }
.cardmodal__price { font-weight: 800; color: var(--c-primary); white-space: nowrap; }
.cardmodal__desc { margin: 8px 0 0; color: var(--muted); }
.cardmodal__close { position: absolute; top: 8px; right: 8px; width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; color: var(--muted); cursor: pointer; z-index: 1; line-height: 1; }
.cardmodal__close i { font-size: 22px; display: block; }

/* TRACK U — redeem action sheet: a bottom-sheet variant of the card modal (matches the mock). */
.cardmodal--sheet { place-items: end center; padding: 0; --tipo: var(--c-primary); }   /* --tipo is set inline per offer → the sheet carries the offer's colour (reds stay for the confirm/warning) */
.cardmodal--sheet .cardmodal__panel { width: 100%; max-width: 480px; max-height: 92vh; border-radius: 20px 20px 0 0;
  animation: sheet-up .26s cubic-bezier(.2, .8, .2, 1); }
.cardmodal--sheet .btn--primary { background: var(--tipo); border-color: color-mix(in srgb, #000 16%, var(--tipo)); box-shadow: 0 3px 14px color-mix(in srgb, var(--tipo) 34%, transparent); }
.cardmodal--sheet :focus-visible { outline-color: var(--tipo); }   /* the focus ring matches the offer, not the app orange */
@keyframes sheet-up { from { transform: translateY(28px); opacity: .6; } to { transform: none; opacity: 1; } }
.btn--danger { background: var(--danger-solid); color: #fff; }
.btn--danger:hover { filter: brightness(1.05); }
.redeem { padding: 20px 18px calc(20px + env(safe-area-inset-bottom)); }
/* centred, boxless header — matches the "Usa l'offerta" band on the card, then a separator */
.redeem__band { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; margin: 2px 0 0; }
.redeem__gift { color: var(--tipo); line-height: 1; }
.redeem__gift i { font-size: 44px; }
.redeem__band--warn .redeem__gift { color: var(--danger-solid); }
.redeem__sep { border: 0; border-top: 1px solid var(--line); margin: 14px 0; }
.redeem__k { font-size: 11px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: color-mix(in srgb, var(--tipo) 80%, var(--ink)); }
.redeem__k--warn { color: var(--danger-solid); }
.redeem__v { font-size: 22px; font-weight: 800; letter-spacing: -.3px; line-height: 1.15; color: var(--ink); overflow-wrap: anywhere; }
.redeem__sub { margin: 0 0 8px; font-size: 15px; font-weight: 700; color: var(--ink); text-align: center; }
.redeem__desc { margin: 0 0 14px; font-size: 14px; color: var(--muted); line-height: 1.5; text-align: center; }
.redeem__note { display: flex; gap: 12px; align-items: center; border-radius: 12px; padding: 13px 15px; margin: 0 0 16px;
  background: color-mix(in srgb, var(--tipo) 10%, var(--surface)); }
.redeem__note i { flex: none; line-height: 1; display: block; color: color-mix(in srgb, var(--tipo) 82%, var(--ink)); }
.redeem__note p { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.45; color: color-mix(in srgb, var(--tipo) 82%, var(--ink)); }
/* the sheet CTAs speak in CAPS like PRENOTA — standard button size, the voice does the work
   (the quiet "più tardi" / "Annulla" stay lowercase); line-height covers a rare 2-line wrap */
.redeem .btn--primary, .redeem .btn--danger { text-transform: uppercase; line-height: 1.2; }
.redeem__note--warn { background: color-mix(in srgb, var(--danger) 12%, var(--surface)); }
.redeem__note--warn i, .redeem__note--warn p { color: var(--danger-solid); }

/* notepad menu — the à-la-carte courses written on lined paper */
.notepad {
  position: relative;
  margin-top: 4px;
  padding: 22px 20px 30px 29px;
  border-radius: var(--radius-card);
  border: 1px solid rgba(53, 49, 43, .13);
  background-color: #f7f2e4;
  background-image: repeating-linear-gradient(#f7f2e4 0 31px, #ccdae6 31px 32px);
  box-shadow: 0 18px 40px -20px rgba(20, 20, 20, .55), 0 1px 0 rgba(0, 0, 0, .05);
  color: #34312b;
  overflow: hidden;
}
.notepad::before { /* the red margin rule */
  content: ''; position: absolute; top: 0; bottom: 0; left: 15px; width: 2px;
  background: rgba(192, 75, 68, .5);
}
.notepad__title {
  font-family: 'Caveat', cursive; font-weight: 700;
  font-size: 42px; line-height: 1; text-align: center; margin-bottom: 6px;
  color: var(--c-primary);
}
.notepad__course { margin-top: 18px; }
.notepad__course:first-of-type { margin-top: 8px; }
.notepad__course-name {
  font-family: 'Caveat', cursive; font-weight: 700;
  font-size: 28px; line-height: 1.1; margin: 0 0 2px;
  color: var(--c-primary);
}
.notepad__dish { margin: 7px 0; }
.notepad__line { display: flex; align-items: baseline; gap: 8px; }
.notepad__dish-name { font-family: 'Caveat', cursive; font-weight: 600; font-size: 25px; line-height: 1.1; }
.notepad__leader { flex: 1 1 auto; border-bottom: 2px dotted rgba(80, 95, 110, .42); transform: translateY(-0.32em); }
.notepad__price { font-family: 'Caveat', cursive; font-weight: 700; font-size: 25px; white-space: nowrap; color: #34312b; }
.notepad__desc { font-family: 'Caveat', cursive; font-weight: 500; font-size: 21px; line-height: 1.05; margin: 1px 0 0; color: #837a69; }

/* Menu style: MODERN — clean, sans-serif, no paper texture */
.notepad--modern { padding: 20px; background-color: var(--surface); background-image: none; border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); color: var(--ink); }
/* subtle on-brand glow from the top so Modern doesn't read as empty (falls back to flat surface) */
@supports (background: color-mix(in srgb, red, blue)) {
  .notepad--modern { background-image:
    repeating-linear-gradient(45deg, color-mix(in srgb, var(--ink) 5%, transparent) 0 1px, transparent 1px 13px),
    radial-gradient(120% 70% at 50% -10%, color-mix(in srgb, var(--c-primary) 9%, transparent), transparent 60%); }
}
.notepad--modern::before { display: none; }
.notepad--modern .notepad__title { font-family: var(--font-ui); font-weight: 800; font-size: 22px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink); }
.notepad--modern .notepad__course-name { font-family: var(--font-ui); font-weight: 700; font-size: 18px; letter-spacing: .06em; text-transform: uppercase; color: var(--c-primary); }
.notepad--modern .notepad__dish-name { font-family: var(--font-ui); font-weight: 600; font-size: 17px; }
.notepad--modern .notepad__price { font-family: var(--font-ui); font-weight: 700; font-size: 17px; color: var(--c-primary); }
.notepad--modern .notepad__desc { font-family: var(--font-ui); font-weight: 400; font-size: 14px; color: var(--muted); }
.notepad--modern .notepad__leader { border: 0; }
/* Moderno only: a hairline after the last dish/drink of each category (not the last category) */
.notepad--modern .notepad__course:not(:last-child) { border-bottom: 1px solid var(--line); padding-bottom: 16px; }

/* Menu style: ELEGANT — refined serif on ivory */
.notepad--elegant { padding: 26px 28px 30px; background: #faf6ee; background-image: none; border: 1px solid rgba(53, 49, 43, .13); box-shadow: var(--shadow-sm); color: #34312b; }
.notepad--elegant::before { display: none; }
.notepad--elegant .notepad__title { position: relative; padding-bottom: 20px; font-family: 'Cormorant', Georgia, serif; font-weight: 600; font-size: 34px; letter-spacing: .01em; color: var(--c-primary); }
/* elegant separator under the title: a faded hairline with a small diamond on it */
.notepad--elegant .notepad__title::before { content: ''; position: absolute; left: 50%; bottom: 9px; transform: translateX(-50%); width: 132px; height: 1px; background: linear-gradient(to right, transparent, rgba(140, 110, 60, .5) 20%, rgba(140, 110, 60, .5) 80%, transparent); }
.notepad--elegant .notepad__title::after { content: ''; position: absolute; left: 50%; bottom: 6px; transform: translateX(-50%) rotate(45deg); width: 7px; height: 7px; background: var(--c-primary); }
.notepad--elegant .notepad__course-name { font-family: 'Cormorant', Georgia, serif; font-weight: 600; font-size: 28px; letter-spacing: .02em; color: var(--c-primary); text-align: center; }
.notepad--elegant .notepad__dish-name { font-family: 'Cormorant', Georgia, serif; font-weight: 600; font-size: 21px; color: #34312b; }
.notepad--elegant .notepad__price { font-family: 'Cormorant', Georgia, serif; font-weight: 600; font-size: 21px; color: #34312b; }
.notepad--elegant .notepad__desc { font-family: var(--font-ui); font-style: italic; font-size: 14px; color: #8a8170; }
.notepad--elegant .notepad__leader { border-bottom: 1px dotted rgba(80, 95, 110, .4); transform: translateY(-0.3em); }

/* Menu-style picker: a mini live mockup of each style (Gestione → Menu) */
.mstyle-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.mstyle { display: flex; flex-direction: column; gap: 6px; padding: 0; background: none; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.mstyle__prev { position: relative; display: block; height: 66px; padding: 7px 8px; border-radius: 9px; border: 1px solid var(--line); overflow: hidden; }
.mstyle.is-active .mstyle__prev { border-color: transparent; outline: 2px solid var(--c-primary); outline-offset: 1px; }
.mstyle__label { text-align: center; font-size: 12px; font-weight: 600; color: var(--muted); }
.mstyle.is-active .mstyle__label { color: var(--c-primary); }
.mstyle__course { display: block; line-height: 1.05; }
.mstyle__dish { display: flex; justify-content: space-between; align-items: baseline; gap: 4px; margin-top: 4px; }
.mstyle__name { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.mstyle__price { white-space: nowrap; }
/* notepad mini: lined cream paper + red margin + handwritten */
.mstyle__prev--notepad { background-color: #f7f2e4; background-image: repeating-linear-gradient(#f7f2e4 0 11px, #ccdae6 11px 12px); }
.mstyle__prev--notepad::before { content: ''; position: absolute; top: 0; bottom: 0; left: 5px; width: 1px; background: rgba(192, 75, 68, .55); }
.mstyle__prev--notepad .mstyle__course { font-family: 'Caveat', cursive; font-weight: 700; font-size: 14px; color: var(--c-primary); padding-left: 4px; }
.mstyle__prev--notepad .mstyle__dish { padding-left: 4px; }
.mstyle__prev--notepad .mstyle__name, .mstyle__prev--notepad .mstyle__price { font-family: 'Caveat', cursive; font-weight: 600; font-size: 12px; color: #34312b; }
/* modern mini: clean dark card + sans */
.mstyle__prev--modern { background-color: var(--surface); background-image: repeating-linear-gradient(45deg, color-mix(in srgb, var(--ink) 10%, transparent) 0 1px, transparent 1px 7px); }
.mstyle__prev--modern .mstyle__course { font-family: var(--font-ui); font-weight: 700; font-size: 8px; letter-spacing: .06em; text-transform: uppercase; color: var(--c-primary); }
.mstyle__prev--modern .mstyle__name { font-family: var(--font-ui); font-weight: 600; font-size: 10px; color: var(--ink); }
.mstyle__prev--modern .mstyle__price { font-family: var(--font-ui); font-weight: 700; font-size: 10px; color: var(--c-primary); }
/* elegant mini: ivory + serif */
.mstyle__prev--elegant { background: #faf6ee; }
.mstyle__prev--elegant .mstyle__course { font-family: 'Cormorant', Georgia, serif; font-weight: 600; font-size: 14px; color: var(--c-primary); }
.mstyle__prev--elegant .mstyle__name, .mstyle__prev--elegant .mstyle__price { font-family: 'Cormorant', Georgia, serif; font-weight: 600; font-size: 12px; color: #34312b; }

/* Condividi share sheet: white QR card + link */
.share-qr { width: 220px; max-width: 72vw; aspect-ratio: 1 / 1; margin: 0 auto; background: #fff; border-radius: 14px; padding: 12px; box-sizing: border-box; }
.share-qr svg { width: 100%; height: 100%; display: block; }
.share-url { margin: 14px 0 0; text-align: center; font-size: 18px; font-weight: 600; line-height: 1.4; color: var(--ink); word-break: break-all; }

/* Menu disponibili — the menu library thumbs (2 per row, card-like) */
.menu-thumbs { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
/* square cards, 2 per row — tap opens the menu/list editor modal (Tony 2026-07-18); no selected-ring anymore */
.menu-thumb { position: relative; display: flex; flex-direction: column; gap: 6px; align-items: center; text-align: center; justify-content: space-between; height: 172px; overflow: hidden; padding: 14px 10px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 14px; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: border-color .15s ease, background-color .15s ease; }
.menu-thumb:active { background: color-mix(in srgb, var(--c-primary) 8%, var(--surface-2)); border-color: color-mix(in srgb, var(--c-primary) 34%, var(--line)); }
.menu-thumb__act { position: absolute; top: 6px; right: 6px; }
.menu-thumb__main { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; flex: 1 1 auto; min-height: 0; overflow: hidden; }
.menu-thumb__ico { line-height: 1; flex: none; }
.menu-thumb__ico i { font-size: 25px; display: block; line-height: 1; }
.menu-thumb__name { flex: none; font-weight: 800; font-size: 18px; line-height: 1.14; color: var(--ink); overflow-wrap: anywhere; }
.menu-thumb__sub { font-size: 11.5px; color: var(--muted); }
.menu-thumb__show { flex: none; }
.menu-thumb__show { display: inline-flex; align-items: center; gap: 7px; }
/* the editable menu/list name at the top of the editor modal (replaces the old pencil-rename) */
.listedit__title { text-align: center; font-size: 22px; font-weight: 700; letter-spacing: -.01em; }
.menu-thumb__showlbl { font-size: 11.5px; color: var(--muted); }

/* customer Menu page: tabs over the active menus */
.menu-tabs { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; }
/* squared buttons (matches the Gestione admin tabs) + a food/drink icon; 1px smaller than before */
.menu-tab { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; padding: 9px 13px; border-radius: 10px; border: 1px solid var(--line); background: transparent; color: var(--muted); font-weight: 600; font-size: 13px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.menu-tab i { flex: 0 0 auto; font-size: 16px; }
.menu-tab.is-active { background: var(--c-primary); border-color: transparent; color: #fff; }
/* the menu editor connects to "Menu disponibili" as one unit (.menu-pair) — no orange ring; it uses the normal card border. */
/* "Menu disponibili" + the selected-menu panel read as ONE connected unit (TRACK Q): they touch, facing corners flattened. */
.menu-pair { display: flex; flex-direction: column; }
.menu-pair > .card:first-child { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.menu-pair > .card:last-child { border-top-left-radius: 0; border-top-right-radius: 0; }
.menu-pair--folded > .card:first-child { border-bottom-left-radius: var(--radius-card); border-bottom-right-radius: var(--radius-card); } /* rounded again when the pair is folded */
/* "Nascosta ai clienti" pill — stamped on a Gestione panel whose customer-facing section is toggled off (TRACK Q). */
/* "Nascosti ai clienti" — a full-width red warning row that bleeds to the card edges (cancels the 16px
   card padding). Sits under the panel header: a red band when the panel is open, a footer band when folded. */
.hidden-tag { display: block; margin: 3px -16px 0; padding: 4px 16px; background: #c0322b; color: #fff; text-align: center; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.card.is-collapsed .hidden-tag { margin-bottom: -16px; border-radius: 0 0 var(--radius-card) var(--radius-card); }
/* A section switched OFF (its .hidden-tag band is present) reads as INACTIVE: icon/title/content greyed +
   the shadow removed (flattened). The red banner AND the on/off switch stay full so it's clearly re-enableable. */
.card:has(.hidden-tag) { box-shadow: none; }
.card:has(.hidden-tag) .panel-ico,
.card:has(.hidden-tag) .section__title,
.card:has(.hidden-tag) .help-btn,
.card:has(.hidden-tag) .card__body > :not(.panel-head):not(.hidden-tag) { opacity: .42; }
.card:has(.hidden-tag) .panel-head::before { opacity: .42; }   /* the ">" collapse chevron */
/* Non-blocking save indicator (Manager): bottom-centre pill; NEVER blocks input (pointer-events:none). TRACK Q. */
.savepill { position: fixed; left: 50%; bottom: 22px; transform: translate(-50%, 16px); z-index: 200; display: inline-flex; align-items: center; gap: 8px; padding: 8px 16px; border-radius: 999px; font-size: 13px; font-weight: 600; color: #fff; box-shadow: 0 8px 26px rgba(0,0,0,.20); opacity: 0; pointer-events: none; transition: opacity .22s ease, transform .22s ease; }
.savepill.is-shown { opacity: 1; transform: translate(-50%, 0); }
.savepill--saving { background: #3a3a3c; }
.savepill--saved { background: #2f8a4e; }
.savepill--error { background: #c0322b; }
.savepill__spin { width: 13px; height: 13px; border: 2px solid rgba(255,255,255,.35); border-top-color: #fff; border-radius: 50%; animation: savespin .7s linear infinite; }
@keyframes savespin { to { transform: rotate(360deg); } }
/* admin header: "< App"  ·  centered "Osteria del Borgo | Admin"  ·  balance */
.apphead__inner--admin { display: flex; align-items: center; justify-content: space-between; gap: 8px; position: relative; }
.admin-head__title { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); white-space: nowrap; font-size: 24px; font-weight: 600; color: var(--header-fg); pointer-events: none; }
.admin-head__biz { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.admin-head__suffix { flex: none; opacity: .5; font-weight: 600; }
.apphead__bal { flex: 0 0 36px; }
/* Manager primary navigation — the two areas as a bold, full-width segmented control (TRACK Q header). */
/* The Manager tabs are a SECOND BAND of the header: full-bleed, square, its own light tint, a white hairline
   at the foot. They live inside .apphead, so the sticky behaviour and the header's shadow come for free —
   always reachable, so you can jump tabs from anywhere without scrolling back up. */
.apphead__tabs { border-bottom: 1px solid color-mix(in srgb, var(--header-fg) 15%, transparent); } /* no background of its own → it IS the header's colour; soft hairline at the foot */
.apphead:has(.apphead__tabs) { border-bottom: 0; } /* the band carries the line — never draw two */
.admin-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 5px; padding: 6px 0; }
.admin-tab2 { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 13px 5px; border: 0; border-radius: 10px; background: transparent; color: var(--muted); font-weight: 700; font-size: 14px; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background .12s ease, color .12s ease; }
.admin-tab2 i { flex: 0 0 auto; }
.admin-tab2 span { white-space: nowrap; }
.admin-tab2.is-active { background: var(--c-primary); color: #fff; box-shadow: var(--shadow-sm); }
.admin-tabs--3 { grid-template-columns: 1fr 1fr 1fr; }
.admin-tabs--3 .admin-tab2 { font-size: 13px; padding: 12px 3px; gap: 5px; }
/* UNDERLINE TABS (only inside the header band). The floating pill is dropped: the active tab is marked by a
   rule in the signature colour sitting ON the band's bottom hairline, which ties the tab to the content below
   it. Nothing has a shape of its own, so nothing can look like it's floating. Placed after the rules above so
   it wins on source order without a specificity fight. */
.apphead__tabs .admin-tabs { gap: 0; padding: 0; }
.apphead__tabs .admin-tab2 {
  position: relative; border-radius: 0; background: none; box-shadow: none;
  padding: 15px 4px 14px; color: color-mix(in srgb, var(--header-fg) 55%, transparent);
}
.apphead__tabs .admin-tab2.is-active { background: none; box-shadow: none; color: var(--c-primary); }
.apphead__tabs .admin-tab2.is-active::after {
  content: ''; position: absolute; left: 12%; right: 12%; bottom: -1px; height: 3px;
  background: var(--c-primary); border-radius: 3px 3px 0 0;
}
/* Big centred group headings that split the Gestione list into I Menu / Il Tuo Marketing / Extra —
   same size as the "OB Manager" header title so the two read as one hierarchy. */
.mgr-group { display: flex; align-items: center; justify-content: center; gap: 9px; text-align: center; font-size: 24px; font-weight: 700; color: var(--ink); margin: 16px 0 0; letter-spacing: -.01em; line-height: 1.15; }
.mgr-group .ti { flex: none; } /* the page-title icon inherits the title colour — same monochrome style as the Statistiche icon */
/* Statistiche screen */
.statcard { background: color-mix(in srgb, var(--c-primary) 10%, var(--surface)); border: 1px solid color-mix(in srgb, var(--c-primary) 26%, var(--line)); border-radius: 12px; padding: 16px; display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; }
.statcard__n { font-size: 34px; font-weight: 800; color: var(--c-primary); line-height: 1; font-variant-numeric: tabular-nums; }
.statcard__l { font-size: 12.5px; color: var(--muted); }
.statrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.statrow__t { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.statrow__title { font-weight: 700; font-size: 15px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.statrow__sub { font-size: 12px; color: var(--muted); }
.statrow__n { flex: none; font-size: 20px; font-weight: 800; color: var(--c-primary); font-variant-numeric: tabular-nums; }
/* tappable stat rows (accordion, one open at a time) + the offer thumb + the detail panel */
.statrow--btn { width: 100%; font: inherit; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: border-color .15s ease; }
.statrow__thumb { width: 44px; height: 44px; flex: 0 0 auto; border-radius: 10px; object-fit: cover; background: var(--tint-bg); border: 1px solid color-mix(in srgb, var(--c-primary) 30%, transparent); }
.statrow__thumb--ph { display: grid; place-items: center; color: var(--c-primary); }
.statrow__thumb--gold { color: #d9a23c; border-color: color-mix(in srgb, #d9a23c 45%, transparent); background: color-mix(in srgb, #d9a23c 12%, var(--surface)); }
.statrow__chev { flex: none; display: inline-flex; color: var(--muted); transition: transform .2s ease; }
.statitem.is-open .statrow { border-color: color-mix(in srgb, var(--c-primary) 45%, var(--line)); border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.statitem.is-open .statrow__chev { transform: rotate(180deg); }
.statrow__detail { padding: 14px; background: color-mix(in srgb, var(--c-primary) 4%, var(--surface)); border: 1px solid color-mix(in srgb, var(--c-primary) 45%, var(--line)); border-top: 0; border-radius: 0 0 10px 10px; }
.statmini-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.statmini { display: flex; flex-direction: column; gap: 1px; padding: 10px 12px; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; }
.statmini__n { font-size: 17px; font-weight: 800; color: var(--c-primary); font-variant-numeric: tabular-nums; }
.statmini__l { font-size: 11.5px; color: var(--muted); }
.statnote { margin: 10px 0 0; font-size: 12px; color: var(--muted); line-height: 1.45; }
/* Statistiche charts — hand-drawn bars, no libraries: the 30-day rhythm + the weekday view */
.statchart { margin-top: 12px; padding: 14px 16px 12px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; }
.statchart__head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 12px; }
.statchart__title { font-weight: 700; font-size: 14.5px; color: var(--ink); }
.statchart__range { font-size: 12px; color: var(--muted); }
.statchart__range strong { color: #d9a23c; }
.statchart__bars { display: flex; align-items: flex-end; gap: 3px; height: 84px; }
.statchart__bar { flex: 1 1 0; min-width: 0; height: calc(var(--h, 0) * 0.84px); min-height: 3px; border-radius: 3px 3px 0 0;
  background: color-mix(in srgb, var(--c-primary) 55%, var(--surface)); }  /* --h is 0–100 (unitless) */
.statchart__bar[style*="--h:0"] { background: color-mix(in srgb, var(--ink) 10%, var(--surface)); }  /* zero days: a quiet stub */
.statchart__bar.is-today { background: var(--c-primary); }
.statchart__axis { display: flex; justify-content: space-between; margin-top: 6px; font-size: 10.5px; color: var(--muted); }
.statweek { display: flex; gap: 8px; }
.statweek__col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 4px; }
.statweek__n { font-size: 11px; font-weight: 650; color: var(--muted); font-variant-numeric: tabular-nums; line-height: 1; }
.statweek__bar { width: 100%; max-width: 34px; height: calc(var(--h, 0) * 0.64px); min-height: 3px; border-radius: 4px 4px 0 0;
  background: color-mix(in srgb, var(--c-primary) 55%, var(--surface)); }
.statweek__bar[style*="--h:0"] { background: color-mix(in srgb, var(--ink) 10%, var(--surface)); }
.statweek__d { font-size: 10.5px; color: var(--muted); line-height: 1; }
.statweek__col.is-best .statweek__bar { background: #d9a23c; }
.statweek__col.is-best .statweek__n { color: #d9a23c; font-weight: 800; }
.statweek__col.is-best .statweek__d { color: var(--ink); font-weight: 700; }
/* Collapsible Manager panels (TRACK Q): tap a panel header to fold it; chevron shows state; the "+" hides when folded. */
.panel-head { position: relative; min-height: 42px; display: flex; align-items: center; padding-left: 15px; cursor: pointer; -webkit-tap-highlight-color: transparent; } /* fixed height so the title never shifts when the "+" hides */
.panel-head::before { content: ''; position: absolute; left: -4px; top: 50%; width: 7px; height: 7px; border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: translateY(-55%) rotate(45deg); transition: transform .18s ease; } /* the ">" sits ~12px from the panel edge, matching the chevron→icon gap (same in Gestione + Impostazioni) */
.card.is-collapsed .panel-head::before { transform: translateY(-50%) rotate(-45deg); }
.card.is-collapsed .card__body > :not(.panel-head):not(.panel-keep) { display: none; }
.app main .card { scroll-margin-top: calc(125px + env(safe-area-inset-top)); } /* when a panel is scrolled open, clear the sticky header AND the sticky tabs */
.card.is-collapsed .panel-head button:not(.help-btn) { display: none; } /* the "?" help stays visible next to the name even when folded */
/* "Lista raggruppata" look (restaurantAdmin.js GESTIONE_GROUPED): a group's sector cards merge into ONE panel
   with hairline dividers, a slightly bigger icon badge, and a detail line under each title. Uses the same
   surface/line/radius tokens as .card, so colours are identical. The class is only present when the flag is on. */
.gest-group { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); overflow: hidden; }
.gest-group > .card { border: 0; border-radius: 0; box-shadow: none; background: transparent; overflow: visible; }
.gest-group > .card + .card { border-top: 1px solid var(--line); }
.gest-group > .card > .card__body { padding-top: 20px; padding-bottom: 20px; } /* a touch taller rows (was 16px) */
.gest-group .panel-ico { width: 41px; height: 41px; border-radius: 12px; } /* ~1.2× the base grouped icon */
.gest-group .panel-ico i { font-size: 22px !important; } /* bump the glyph inside the bigger grouped badge (overrides icon()'s inline 15px); Disponibilità, ungrouped, stays 15px */
/* Pointer at the foot of Gestione when a section is switched off, so a hidden section is never "lost".
   Outlined in the business's signature colour (--c-primary) with an attention icon, so it actually gets seen. */
.gest-hidden-note {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin: 2px 0 0; padding: 12px 14px;
  border: 1.5px solid color-mix(in srgb, var(--c-primary) 60%, transparent);
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--c-primary) 8%, transparent);
  color: var(--c-primary); font-size: 13px; font-weight: 600; text-align: center;
}
.gest-hidden-note .ti { flex: none; }
.section__sub { color: var(--muted); opacity: .5; font-size: 12.5px; line-height: 1.3; font-weight: 400; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* One FIXED size for every Manager panel title that has an icon badge — both the direct-sibling layout
   (panelHead: Archivio, menu/drink editors) AND the nested layout (sectionHead: Il Ristorante, Il Bar,
   Specialità, Eventi & Speciali, Offerte Automatiche, Carta Fedeltà, Disponibilità e Turni). Customer
   .section__title (no .panel-ico anywhere) stays 22px. */
/* Every Manager section-panel title: one fixed size, a touch dimmed (75%), so the full-white group titles
   lead the hierarchy. Manager-scoped via .container--wide (the customer app uses .container, unaffected);
   the panel-ico/.menupanel selectors also cover any Manager title rendered outside .container--wide. */
.container--wide .section__title,
.panel-ico ~ .section__title,
.cluster:has(.panel-ico) .section__title,
.menupanel .section__title { font-size: 18px; color: color-mix(in srgb, var(--ink) 75%, var(--surface)); } /* names at 75%, not full white */
/* per-panel identity badge (Gestione): a small tinted square, its colour set inline via --pi.
   Stays visible when the panel is collapsed, so each panel keeps its identity at a glance. */
.panel-ico { flex: 0 0 auto; width: 29px; height: 29px; display: grid; place-items: center; border-radius: 9px; color: var(--pi, var(--c-primary)); background: color-mix(in srgb, var(--pi, var(--c-primary)) 15%, var(--surface)); }
/* per-panel "?" help — sits in the freed header corner; muted so it stays secondary to the identity badge */
.help-btn { flex: 0 0 auto; display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: 0; background: none; color: var(--muted); border-radius: 50%; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: color .15s ease, background .15s ease; }
.help-btn:active { color: var(--c-primary); background: var(--tint-bg); }
@media (hover: hover) { .help-btn:hover { color: var(--c-primary); background: var(--tint-bg); } }
.help-body { color: var(--ink); font-size: 14.5px; line-height: 1.55; }
.help-body p { margin: 0 0 10px; }
.help-body p:last-child { margin-bottom: 0; }
/* per-turno "lista principale" button — full width, squared corners (deliberately not a pill) */
.turno-main { display: flex; align-items: center; gap: 8px; width: 100%; margin-top: 2px; padding: 10px 12px; border-radius: 8px; border: 1px dashed var(--line); background: transparent; color: var(--muted); font-family: var(--font-ui); font-weight: 600; font-size: 13.5px; text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.turno-main.is-set { border-style: solid; border-color: color-mix(in srgb, var(--c-primary) 40%, var(--line)); color: var(--ink); background: color-mix(in srgb, var(--c-primary) 6%, var(--surface)); }
.turno-main > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the ONE "Aggiungi…" button — full width, squared, subtle (replaces every header "+") */
.add-btn { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; padding: 11px 12px; border-radius: 8px; border: 1px dashed color-mix(in srgb, var(--muted) 42%, var(--line)); background: transparent; color: var(--ink); font-family: var(--font-ui); font-weight: 600; font-size: 14px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.add-btn:active { background: color-mix(in srgb, var(--muted) 9%, var(--surface)); }
.add-btn--danger { border-color: color-mix(in srgb, var(--danger-solid) 48%, var(--line)); color: var(--danger-solid); }
.add-btn--danger:active { background: color-mix(in srgb, var(--danger-solid) 9%, var(--surface)); }
/* the selected menu/drink EDITOR sits a shade lighter than its picker above, so the picker reads as a
   section header and the two separate visually (menu-pair = picker card + this editor card). */
/* (Session 30: the editor's lighter shade removed — one uniform dark background, Tony's call.) */
/* The selected menu/list NAME is the zone's real headline — same scale as the group titles (.mgr-group). */
.menupanel__name { font-size: 24px; font-weight: 700; color: var(--ink); letter-spacing: -.01em; line-height: 1.15; }
/* Item rows read as CARDS — the same surface recipe as the Offerte Automatiche panels. Applies in the
   menu/drink editors and in every .card--rows panel (Specialità · Eventi & Speciali · Carta Fedeltà · Archivio). */
.menupanel .row, .card--rows .row { background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; padding: 11px 12px; }
.is-hidden { display: none !important; }
.ge-day { flex: 0 0 82px; font-size: 13px; color: var(--muted); }
.ge-day + .input { flex: 1; width: auto; min-width: 0; }

/* ============================================================================
   Manager app — PIN lock screen (managerApp.js). A clean app-style passcode pad.
   --mgr-accent is set inline from the business brand colour.
   ============================================================================ */
.mgrgate { min-height: 100svh; display: grid; place-items: safe center; padding: 28px 24px; background: var(--brand-header-bg, var(--tint-bg)); overflow-y: auto; } /* a business with a dark brand header (Pane&Vino = olive) uses it as the login bg too; others keep the mattone tint */
/* Pane&Vino: warm the login's dark surfaces (inputs / Crea account / social / PRESTO pills) into the
   olive family so nothing reads brown against the olive bg. Scoped by data-property → other clients keep
   their charcoal surfaces. The Accedi button (mattone) + lock/MANAGER (gold) are untouched. */
:root[data-property="osteria-main"] .mgrgate { --surface: #272d1c; --tint-bg: #313823; }
.mgrgate__card { width: 100%; max-width: 330px; text-align: center; }
.mgrgate__lock { width: 66px; height: 66px; margin: 0 auto 16px; display: grid; place-items: center; border-radius: 50%; color: var(--on-accent, #fff); background: var(--mgr-accent); box-shadow: 0 12px 30px rgba(0,0,0,.18); }
.mgrgate__brand { font-size: 21px; font-weight: 800; letter-spacing: -.01em; margin: 0; color: var(--ink); }
.mgrgate__tag { font-size: 11.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--mgr-accent); margin: 3px 0 0; }
.mgrgate__sub { color: var(--muted); font-size: 14.5px; margin: 18px 0 0; }
.mgrgate__dots { display: flex; gap: 15px; justify-content: center; margin: 16px 0 0; }
.mgrdot { width: 13px; height: 13px; border-radius: 50%; border: 1.5px solid var(--mgr-accent); transition: background .12s ease; }
.mgrdot.is-on { background: var(--mgr-accent); }
.mgrgate__err { color: var(--danger, #c0322b); font-size: 13px; margin: 11px 0 0; min-height: 1.1em; }
.mgrgate__pad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 12px auto 0; max-width: 272px; }
.mgrkey { width: 72px; height: 72px; justify-self: center; border-radius: 50%; border: 1px solid var(--line); background: var(--surface); font-size: 25px; font-weight: 500; color: var(--ink); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background .1s, transform .05s; }
.mgrkey:active { background: var(--tint-bg); transform: scale(.95); }
.mgrkey--ghost { border: 0; background: none; pointer-events: none; }
.mgrkey--del { font-size: 21px; border: 0; background: none; }
.mgrgate__note { color: var(--muted); font-size: 11.5px; margin: 22px 0 0; line-height: 1.4; }
.mgrgate__link { display: inline-block; margin: 13px 0 0; font-size: 13.5px; color: var(--mgr-accent); text-decoration: none; font-weight: 600; }
.mgrgate .shake { animation: mgrshake .4s ease; }
@keyframes mgrshake { 10%,90%{transform:translateX(-1px)} 20%,80%{transform:translateX(2px)} 30%,50%,70%{transform:translateX(-5px)} 40%,60%{transform:translateX(5px)} }
/* entrance + unlock-spring */
.mgrgate__card { animation: mgrIn .42s ease both; }
@keyframes mgrIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.mgrgate.is-unlocked .mgrgate__lock { animation: mgrPop .5s ease; }
@keyframes mgrPop { 0% { transform: scale(1); } 45% { transform: scale(1.14); } 100% { transform: scale(1); } }
.mgrgate.is-unlocked .mgrdot { background: var(--success); border-color: var(--success); transition: background .2s, border-color .2s; }
.mgrgate.is-unlocked .mgrgate__card { animation: mgrOut .5s ease forwards; animation-delay: .14s; }
@keyframes mgrOut { to { opacity: 0; transform: scale(.97); } }
@media (prefers-reduced-motion: reduce) {
  .mgrgate__card, .mgrgate.is-unlocked .mgrgate__lock, .mgrgate.is-unlocked .mgrgate__card { animation: none; }
}
/* the PIN dots + keypad live inside a modal here (not the full-screen .mgrgate): give the modal the
   accent the dots colour themselves with, and let them shake on a wrong code. */
.cardmodal { --mgr-accent: var(--c-primary, #c15c2c); }
.cardmodal .shake { animation: mgrshake .4s ease; }
.cardmodal .mgrgate__dots, .cardmodal .mgrgate__pad { justify-content: center; }

/* Touch devices: kill accidental double-tap-to-zoom (and the legacy 300ms tap delay) app-wide.
   `manipulation` still allows scrolling AND pinch-to-zoom, so accessibility is preserved. */
html, body { touch-action: manipulation; }
/* …but NEVER on form fields: `touch-action: manipulation` on the page root blocks the on-screen
   keyboard in an installed iOS PWA (Safari is fine — standalone-only). Exempt inputs so they type. */
input, textarea, select, [contenteditable="true"] { touch-action: auto; -webkit-user-select: text; user-select: text; }

/* ── Area Riservata (TRACK R) ─────────────────────────────────────────────────────────── */
/* Customer "temporarily off" screen — calm, branded, themed to the business colour. */
.pausescreen { min-height: 100svh; display: grid; place-items: safe center; padding: 32px 26px; background: var(--tint-bg); }
.pausescreen__card { width: 100%; max-width: 360px; text-align: center; background: var(--surface); border: 1px solid var(--line); border-radius: 20px; padding: 40px 30px; box-shadow: 0 20px 50px rgba(0,0,0,.08); animation: mgrIn .42s ease both; }
.pausescreen__badge { width: 70px; height: 70px; margin: 0 auto 20px; display: grid; place-items: center; border-radius: 50%; color: var(--pause-accent); background: color-mix(in srgb, var(--pause-accent) 14%, var(--surface)); }
.pausescreen__brand { font-size: 22px; font-weight: 800; letter-spacing: -.01em; margin: 0; color: var(--ink); }
.pausescreen__title { font-size: 16px; font-weight: 700; color: var(--pause-accent); margin: 14px 0 0; }
.pausescreen__body { font-size: 14.5px; color: var(--muted); line-height: 1.5; margin: 8px 0 0; }
.pausescreen__body--lead { margin-top: 16px; font-size: 15.5px; } /* the message stands alone (closed screen, no accent title above) */
.pausescreen__photo { margin: 20px 0 0; border-radius: 14px; overflow: hidden; aspect-ratio: 16 / 10; background: color-mix(in srgb, var(--pause-accent) 8%, var(--surface)); }
.pausescreen__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Manager "Area riservata" panel — a subtle red frame + red identity badge. */
.area-card { border-color: color-mix(in srgb, #c0322b 30%, var(--line)); }
.area-ico { --pi: #c0322b; }
.area-grouplabel { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
/* Filled action buttons (Tony) — white text on a solid fill so they carry weight in this area.
   Amber = caution, red = danger; the safe actions use the copper .btn--primary. Mirrors its gradient finish. */
.area-btn--warn, .area-btn--danger, .area-btn--go { color: #fff; border-color: color-mix(in srgb, #000 18%, var(--_ab)); background: linear-gradient(108deg, color-mix(in srgb, #fff 22%, var(--_ab)) 0%, var(--_ab) 46%, color-mix(in srgb, var(--_ab) 84%, #000) 100%); box-shadow: inset 0 1px 0 rgba(255,255,255,.24), 0 6px 18px color-mix(in srgb, var(--_ab) 30%, transparent); }
.area-btn--warn { --_ab: #45647c; }   /* caution — cool steel-blue, clearly distinct from the warm copper */
/* "Take your data with you" — the amber block inside the close-the-account confirm. Amber on
   purpose: it is neither a danger (the red button below it is) nor a note to skim. It is the last
   moment his content is reachable, and it carries the button rather than pointing at one. */
.area-takeaway { border: 1px solid rgba(243, 177, 75, .42); background: rgba(243, 177, 75, .09);
  border-radius: 12px; padding: 12px 13px; margin: 0 0 14px; }
.area-takeaway p { margin: 0 0 10px; font-size: 13.5px; line-height: 1.45; color: #f0cf9a; }
.area-takeaway .btn { width: 100%; background: rgba(243, 177, 75, .16); border-color: rgba(243, 177, 75, .5); color: #f6dfb4; }
.area-takeaway__when { display: block; margin: 7px 2px 0; font-size: 11.5px; color: var(--muted); }
/* "on but invisible" — the Carta is switched on with an empty reward ladder, so the customer tab
   is (correctly) hidden. Amber, inline, and only while that is true: it is an unfinished setup,
   not an error. */
.carta-warn { display: flex; gap: 8px; align-items: flex-start; margin: 0; padding: 10px 12px;
  border: 1px solid rgba(243, 177, 75, .4); background: rgba(243, 177, 75, .09);
  border-radius: 11px; font-size: 13px; line-height: 1.45; color: #f0cf9a; }
.carta-warn svg { flex: none; margin-top: 1px; }
.area-btn--danger { --_ab: #c0322b; } /* danger — red */
.area-btn--go { --_ab: #2f8a4e; }     /* reactivate — green "go" */
.area-btn--warn:hover, .area-btn--danger:hover, .area-btn--go:hover { filter: brightness(1.05); }

/* "App in pausa" banner (Manager) — the owner keeps working while the customer app is off, so keep it unmissable.
   Centered content + full-width button, a lifted shadow + a 2px border so it clearly floats above the scrolling content. */
.mgr-pausebanner { position: sticky; top: calc(env(safe-area-inset-top) + 110px); /* clears the header + its tabs band */ z-index: 15; display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; padding: 12px 14px; border-radius: 12px; background: color-mix(in srgb, #d97706 16%, var(--surface)); border: 2px solid color-mix(in srgb, #d97706 55%, transparent); box-shadow: 0 10px 28px rgba(0,0,0,.32); }
.mgr-pausebanner__txt { display: inline-flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 8px; font-size: 13.5px; color: var(--ink); }
.mgr-pausebanner__txt i { color: #d97706; }
.mgr-pausebanner__btn { width: 100%; background: #2f8a4e; color: #fff; border-color: #2f8a4e; }
.mgr-pausebanner__btn:hover { filter: brightness(1.05); }
.area-note { display: flex; gap: 7px; align-items: flex-start; font-size: 11.5px; color: var(--muted); line-height: 1.45; margin: 2px 0 0; }
.area-note i { margin-top: 1px; flex: 0 0 auto; }
/* live feedback under the "type the name" field in the close-account confirm */
.area-match { color: var(--muted); }
.area-match.is-ok { color: #2f8a4e; font-weight: 600; }

/* Manager login (managerAuth.js) — email/password form + coming-soon social buttons */
.mgrauth { max-width: 340px; }
.mgrauth__form { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; text-align: left; }
.mgrauth__form .input { width: 100%; }
.mgrauth__form .mgrgate__err { text-align: center; margin: 2px 0 0; }
.mgrauth__switchtext { font-size: 13.5px; color: var(--muted); margin: 18px 0 8px; text-align: center; }
.mgrauth__switchbtn { margin: 0; }
.mgrauth__or { display: flex; align-items: center; gap: 12px; margin: 20px 0 14px; color: var(--muted); font-size: 12px; letter-spacing: .04em; }
.mgrauth__or::before, .mgrauth__or::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.mgrauth__social { display: grid; gap: 8px; }
.mgrsocial { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border: 1px solid var(--line); border-radius: var(--radius, 12px); background: var(--surface); color: var(--ink); font-size: 14.5px; font-weight: 500; cursor: not-allowed; opacity: .72; }
.mgrsocial span { flex: 1; text-align: left; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mgrsocial em { flex: none; font-style: normal; font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap; color: var(--muted); background: var(--tint-bg); padding: 2px 8px; border-radius: 999px; }
.mgrsocial .ti { font-size: 20px; color: var(--ink); }

/* ============ Stile dell'App — Classico / Elegante / Moderno ============ */
/* Elegante = the current default look, so it needs no overrides. */

/* Menu Fisso cards + Offerte (Classico) = a warm dark "wooden plaque" done in PURE CSS — no image, so
   it can never flash or re-load a background. Gold border + carved text keep the character. */
.setmenu--notepad, .offer-card--notepad {
  position: relative; overflow: hidden;
  background-color: #2a1d10;
  background-image: linear-gradient(157deg, rgba(122, 86, 46, .34) 0%, rgba(48, 33, 18, .12) 44%, rgba(16, 11, 5, .34) 100%);
  border: 2px solid #4f3719; border-radius: var(--radius-card); box-shadow: var(--shadow-md);
}
.setmenu--notepad .card__body { position: relative; z-index: 1; padding: clamp(11px, 8cqi, 16px); }
.offer-card--notepad .offer-card__img { position: relative; z-index: 1; } /* product photo above the plaque */
/* handwriting font + a soft "engraved into the wood" treatment: dark depth shadow + a faint warm top light */
/* handwriting price + description, carved deeper into the wood */
.setmenu--notepad .setmenu__price, .setmenu--notepad .muted,
.offer-card--notepad .card__title {
  font-family: 'Caveat', cursive;
  text-shadow: 0 1px 1px rgba(0, 0, 0, .72), 0 2px 3px rgba(0, 0, 0, .45), 0 -1px 1px rgba(255, 240, 215, .30);
}
/* Title = a dark rounded chip (like the "Aperitivo 8€" pill): centered, UI font, icon in front. */
.setmenu--notepad .setmenu__name {
  align-self: center; max-width: 100%;
  display: inline-flex; align-items: center; justify-content: center; gap: .4em; white-space: nowrap;
  font-family: var(--font-ui); font-weight: 600; font-size: clamp(9px, 7.5cqi, 13.5px); letter-spacing: .01em;
  color: #fbe7d0; background: rgba(0, 0, 0, .46); border: 1px solid rgba(255, 236, 208, .14);
  padding: clamp(3px, 3cqi, 5px) clamp(7px, 7cqi, 12px); border-radius: var(--radius-card); box-shadow: 0 2px 6px rgba(0, 0, 0, .35);
}
.setmenu--notepad .setmenu__name .ti { font-size: 1.15em; color: #ffdca6; flex: none; }
.setmenu--notepad .setmenu__price {
  font-size: clamp(24px, 22cqi, 40px); font-weight: 700; color: #ffdca6; /* sized so a 2-digit price fits fully inside the card (stays centred) */
  -webkit-text-stroke: 0.6px #ffdca6; /* extra weight — Caveat itself maxes out at 700 */
}
/* tight line-height so a 2-line description reads as one block */
.setmenu--notepad .muted { font-size: clamp(15px, 14cqi, 22px); font-weight: 400; color: #f1e4d0 !important; line-height: 1.12; }

/* Offerte on the wood: a scrim + light text over the body; the product photo stays clear on the left. */
.offer-card--notepad .offer-card__body { position: relative; z-index: 1; background: linear-gradient(180deg, rgba(16, 11, 5, .16), rgba(16, 11, 5, .40)); }
.offer-card--notepad .card__title { font-size: 28px; font-weight: 700; color: #fbe7d0; }
.offer-card--notepad .offer-card__body .muted, .offer-card--notepad .offer-card__body .small { font-family: var(--font-ui); font-size: 15px; font-weight: 400; line-height: 1.45; color: #f1e4d0 !important; text-shadow: 0 1px 2px rgba(0, 0, 0, .55); }
.offer-card--notepad .chip { background: rgba(0, 0, 0, .34); color: #fbe7d0; border: 0; }

/* Moderno cards (fisso + offerte) = the menu's diagonal hatch over the existing dark background. */
.setmenu--modern, .offer-card--modern {
  background-image: repeating-linear-gradient(45deg, color-mix(in srgb, var(--ink) 7%, transparent) 0 1px, transparent 1px 13px);
}

/* Specialità del giorno (n.2), Classico = the menu's notepad lined-paper look. */
.card--feature--notepad {
  background-color: #f7f2e4;
  background-image: repeating-linear-gradient(#f7f2e4 0 31px, #ccdae6 31px 32px);
  border: 1px solid rgba(53, 49, 43, .16); color: #34312b;
}
/* Specialità text = the Menu's handwriting (Caveat), same as the notepad dishes */
.card--feature--notepad .row__title, .card--feature--notepad .price { color: #34312b; font-family: 'Caveat', cursive; }
.card--feature--notepad .row__title { font-weight: 600; font-size: 23px; line-height: 1.1; }
.card--feature--notepad .price { font-weight: 700; font-size: 23px; }
.card--feature--notepad .row__sub { color: #837a69 !important; font-family: 'Caveat', cursive; font-weight: 500; font-size: 20px; line-height: 1.05; }
.card--feature--elegant { background: #faf6ee; border: 1px solid rgba(140, 110, 60, .24); }
/* same ink as the Elegante menu — the title/price were inheriting white and vanishing on the cream card */
.card--feature--elegant .row__title, .card--feature--elegant .price { color: #34312b; }
.card--feature--elegant .row__sub { color: #8a8170 !important; }
.card--feature--modern {
  background-color: var(--surface);
  background-image: repeating-linear-gradient(45deg, color-mix(in srgb, var(--ink) 6%, transparent) 0 1px, transparent 1px 13px);
  border: 1px solid var(--line);
}

/* ============================================================================
   TRACK V — Allergeni & Diete: the 14-allergen + veg icon set, the per-item icon
   rows, the two customer filter buttons/modals, and the dish-card big list.
   Allergens = amber, diets = green (semantic, separate from the business accent).
   ============================================================================ */
:root {
  --alg: #b3781f; --alg-fill: #faf2e4; --alg-line: #e6cf9f;
  --veg: #3f9d4f; --veg-fill: #eaf5ec; --veg-line: #bfe2c6; --veg-ink: #2f7d3c;
  --alg-off: #c0392b;
}
:root[data-theme="dark"] {
  --alg: #dcab54; --alg-fill: color-mix(in srgb, #dcab54 15%, var(--surface)); --alg-line: color-mix(in srgb, #dcab54 42%, var(--surface));
  --veg: #6cc47a; --veg-fill: color-mix(in srgb, #6cc47a 15%, var(--surface)); --veg-line: color-mix(in srgb, #6cc47a 40%, var(--surface)); --veg-ink: #8fd79a;
}

/* one circular OUTLINE chip — hollow ring + glyph (no fill), so it's light and identical everywhere */
.alg { --c: var(--alg);
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; vertical-align: middle;
  width: var(--s, 22px); height: var(--s, 22px); border-radius: 999px; background: transparent; border: 1px solid var(--c); color: var(--c); }
.alg svg { width: 66%; height: 66%; display: block; }
.alg--veg { --c: var(--veg); }
.alg--off { --c: #fff; background: var(--alg-off); border-color: var(--alg-off); }

.iconrow { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; align-items: center; }

/* the two customer filter buttons — no box, just icon + label; pinned top-right INSIDE the paper menu */
.paper-filters { display: flex; justify-content: flex-end; gap: 18px; margin: 2px 2px 12px; }
.pfilter { display: flex; flex-direction: column; align-items: center; gap: 5px; border: 0; background: transparent; padding: 2px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.pfilter__ic { position: relative; display: inline-flex; }
.pfilter__lbl { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; font-weight: 700; color: var(--muted); }
.pfilter.is-on .pfilter__lbl { color: var(--c-primary); }
.fbadge { position: absolute; top: -6px; right: -8px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--c-primary); color: #fff; font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; box-shadow: var(--shadow-sm); }
/* Elegante: centre the two filters (like its centred course names), sit a touch higher + closer to the first course */
.notepad--elegant .paper-filters { justify-content: center; margin: -10px 2px 2px; }
/* Classico + Moderno: pull the filters (and the courses below) up to compress the empty space at the paper's top */
.notepad--modern .paper-filters,
.notepad:not(.notepad--elegant):not(.notepad--modern) .paper-filters { margin-top: -12px; margin-bottom: 4px; }
/* Classico (ruled paper): fill the icon circles white so the ruled lines don't show through them (this style only) */
.notepad .alg { background: #fff; }
.notepad--elegant .alg, .notepad--modern .alg { background: transparent; }

/* the two filter modals (built on the shared .cardmodal overlay) */
.algfilter__lede { margin: 8px 0 4px; text-align: center; color: var(--muted); font-size: 13.5px; line-height: 1.45; }
.veg-opts { display: flex; flex-direction: column; gap: 10px; margin: 18px 0 6px; }
.veg-opt { display: flex; align-items: center; gap: 13px; border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px;
  font-weight: 700; font-size: 15px; color: var(--muted); background: var(--surface); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.veg-opt.is-on { border-color: var(--veg-line); background: var(--veg-fill); color: var(--veg-ink); }
.algmodal { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; margin: 18px 0 8px; }
.algrow { display: flex; align-items: center; gap: 10px; border: 1px solid var(--line); border-radius: 11px; padding: 9px 10px;
  font-size: 13px; font-weight: 600; color: var(--ink); background: var(--surface); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.algrow.is-on { border-color: var(--alg-line); background: var(--alg-fill); }
.alg-disclaim { display: flex; gap: 9px; align-items: flex-start; margin-top: 14px; padding: 11px 12px; border-radius: 10px;
  background: color-mix(in srgb, var(--c-primary) 10%, var(--surface)); color: var(--ink); font-size: 12px; line-height: 1.45; }
.alg-disclaim i { flex: 0 0 auto; font-size: 16px; margin-top: 1px; color: var(--c-primary); }
.alg-empty { text-align: center; color: var(--muted); padding: 26px 12px; font-size: 14px; }

/* the dish card's big labelled list (Contiene · Diete), after the description */
.card__alg { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.card__alg h4 { margin: 0 0 11px; font-size: 11px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
.biglist { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 10px; }
.bigitem { display: flex; align-items: center; gap: 10px; font-size: 13.5px; font-weight: 600; color: var(--ink); }

/* the owner "Filtri" block — a quiet bordered panel (like the Descrizione box) that groups the
   contents; the "Filtri" label sits OUTSIDE it, matching the other field labels. */
.filtri { display: flex; flex-direction: column; gap: 2px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); padding: 10px 13px 13px; }
.filtri__lbl { font-size: 12px; font-weight: 600; color: var(--muted); margin: 10px 0 8px; }
.filtri__lbl:first-child { margin-top: 2px; }
.ftoggles { display: flex; flex-wrap: wrap; gap: 9px; margin-bottom: 15px; }
.ftoggle { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--line); border-radius: 999px; padding: 7px 13px 7px 8px;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--muted); background: var(--surface); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.ftoggle.is-on { border-color: var(--veg-line); color: var(--veg-ink); background: var(--veg-fill); }
.fchips { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.fchip { display: flex; align-items: center; gap: 9px; border: 1px solid var(--line); border-radius: 10px; padding: 7px 9px;
  font-family: inherit; font-size: 12.5px; font-weight: 500; color: var(--ink); background: var(--surface); cursor: pointer; text-align: left; -webkit-tap-highlight-color: transparent; }
.fchip span { min-width: 0; }
.fchip.is-on { border-color: var(--alg-line); background: var(--alg-fill); }

/* ============================================================================
   TELAIO HQ — Tony's control room (#/hq). Its OWN identity: the Telaio landing
   palette (dark charcoal + teal/green/gold), deliberately NOT the business theme.
   Scoped under .hq so nothing leaks into the customer/Manager apps.
   ========================================================================== */
.hq {
  --hq-bg1: #161719; --hq-bg2: #0e0f10;
  --hq-panel: rgba(32, 34, 32, .72); --hq-panel2: rgba(44, 49, 45, .7);
  --hq-ink: #e5e5e5; --hq-soft: #9aa39d; --hq-bright: #f2f7f4;
  --hq-line: #262b28; --hq-line2: #39403b;
  --hq-teal: #2aa595; --hq-green: #1e6b4d; --hq-gold: #f3b14b; --hq-good: #4bb98a;
  --hq-cream: #f4f1e8;
  min-height: 100vh; min-height: 100dvh; color: var(--hq-ink);
  background:
    radial-gradient(900px 500px at 15% -10%, rgba(20, 145, 134, .16), transparent 60%),
    radial-gradient(800px 480px at 90% 0%, rgba(30, 107, 77, .15), transparent 55%),
    linear-gradient(var(--hq-bg1), var(--hq-bg2));
}
.hq .input { background: var(--hq-panel); border: 1px solid var(--hq-line2); color: var(--hq-bright); }
.hq .input:focus { border-color: var(--hq-teal); outline: none; }
.hq .input::placeholder { color: var(--hq-soft); }
.hq-btn-primary { background: linear-gradient(150deg, var(--hq-green), var(--hq-teal)); color: #fff; border: none; }
.hq-btn-primary:hover { filter: brightness(1.08); }

/* ---- the gate (login / not-allowed / splash) ---- */
.hqgate { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center;
  padding: calc(24px + env(safe-area-inset-top, 0px)) 24px calc(24px + env(safe-area-inset-bottom, 0px)); }
.hqgate__card { width: 100%; max-width: 360px; background: var(--hq-panel); border: 1px solid var(--hq-line2);
  border-radius: 20px; padding: 30px 26px 24px; display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 40px 80px rgba(0, 0, 0, .5), 0 0 0 1px rgba(255, 255, 255, .05) inset; }
.hqgate__lock { width: 54px; height: 54px; border-radius: 15px; display: grid; place-items: center; margin: 0 auto 2px;
  background: rgba(42, 165, 149, .12); color: var(--hq-teal); }
.hqgate__brand { margin: 0; text-align: center; font-size: 24px; font-weight: 800; letter-spacing: -.01em; color: var(--hq-bright); }
.hqgate__brand em { font-style: normal; color: var(--hq-teal); }
.hqgate__sub { margin: 0 0 6px; text-align: center; font-size: 13px; color: var(--hq-soft); line-height: 1.5; }
.hqgate__form { display: flex; flex-direction: column; gap: 10px; }
.hqgate__err { margin: 0; min-height: 1em; text-align: center; font-size: 12.5px; color: #e08578; }
.hqgate__note { margin: 8px 0 0; text-align: center; font-size: 12px; color: var(--hq-soft); }
.hqgate__note a { color: var(--hq-teal); text-decoration: none; }

/* ---- Home ---- */
.hq-home { max-width: 1100px; margin: 0 auto; padding: 0 16px calc(40px + env(safe-area-inset-bottom, 0px)); }
.hq-head { display: flex; align-items: center; gap: 10px; border-bottom: 1px solid var(--hq-line);
  padding: calc(16px + env(safe-area-inset-top, 0px)) 2px 13px; }
.hq-head__mark { font-size: 18px; font-weight: 800; letter-spacing: -.01em; color: var(--hq-bright); }
.hq-head__mark em { font-style: normal; color: var(--hq-teal); }
.hq-head__who { margin-left: auto; font-size: 11.5px; font-weight: 700; color: var(--hq-cream);
  background: var(--hq-panel2); border: 1px solid var(--hq-line2); border-radius: 999px; padding: 4px 11px;
  max-width: 46vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hq-head__out { border: 1px solid var(--hq-line2); background: var(--hq-panel); color: var(--hq-soft);
  border-radius: 10px; width: 34px; height: 30px; display: grid; place-items: center; cursor: pointer; }
.hq-head__out:hover { color: var(--hq-bright); border-color: var(--hq-teal); }
.hq-main { display: flex; flex-direction: column; gap: 14px; padding-top: 16px; }
.hq-stats { display: flex; gap: 8px; }
.hq-stat { flex: 1; background: var(--hq-panel); border: 1px solid var(--hq-line); border-radius: 12px; padding: 10px 12px; }
.hq-stat b { display: block; font-size: 22px; font-weight: 800; color: var(--hq-bright); font-variant-numeric: tabular-nums; line-height: 1.15; }
.hq-stat b i { font-style: normal; font-size: 13px; color: var(--hq-soft); }
.hq-stat span { font-size: 11.5px; color: var(--hq-soft); letter-spacing: .02em; }
.hq-stat--gold b { color: var(--hq-gold); }
.hq-stat--teal b { color: var(--hq-teal); }
.hq-stat--good b { color: var(--hq-good); }
.hq-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.hq-tile { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 9px; min-height: 118px;
  background: var(--hq-panel); border: 1px solid var(--hq-line2); border-radius: 16px; padding: 15px 14px 13px;
  font-family: inherit; text-align: left; color: inherit; cursor: pointer; transition: border-color .2s, transform .2s;
  -webkit-tap-highlight-color: transparent; }
.hq-tile:hover { border-color: var(--hq-teal); transform: translateY(-2px); }
.hq-tile__ic { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center;
  background: rgba(42, 165, 149, .12); color: var(--hq-teal); }
.hq-tile--gold .hq-tile__ic { background: rgba(243, 177, 75, .12); color: var(--hq-gold); }
.hq-tile__tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.hq-tile__tx b { font-size: 15.5px; font-weight: 700; color: var(--hq-bright); line-height: 1.2; }
.hq-tile__tx span { font-size: 12px; color: var(--hq-soft); line-height: 1.35; }
.hq-tile--new { grid-column: 1 / -1; flex-direction: row; align-items: center; min-height: 0; padding: 14px 16px;
  background: linear-gradient(150deg, rgba(30, 107, 77, .5), rgba(42, 165, 149, .34)); border-color: rgba(42, 165, 149, .55); }
.hq-tile--new .hq-tile__ic { background: rgba(255, 255, 255, .14); color: #fff; }
.hq-tile--new .hq-tile__tx b { font-size: 16.5px; }
.hq-tile--new .hq-tile__tx span { color: rgba(244, 241, 232, .78); }
.hq-foot { margin: 8px 2px 0; font-size: 11.5px; color: var(--hq-soft); }
/* The update block at the foot of HQ Home (#3-e, Tony's design): separator · version line · button */
.hq-update { margin: 18px 2px 0; padding-top: 14px; border-top: 1px solid var(--hq-line); display: flex; flex-direction: column; align-items: center; gap: 10px; }
.hq-update .hq-foot { margin: 0; }
.hq-update__btn { font-size: 13px; padding: 9px 16px; }
@media (min-width: 760px) { /* iPad/desktop: the wide tile joins the grid as a taller twin-width card */
  .hq-home { padding: 0 24px 48px; }
  .hq-grid { grid-template-columns: repeat(3, 1fr); }
  .hq-tile--new { grid-column: span 3; }
}
@media (prefers-reduced-motion: reduce) { .hq-tile { transition: none; } .hq-tile:hover { transform: none; } }

/* ---- "Le mie app" inside HQ: reskin the old .su-* pieces to the HQ palette ---- */
.hq-head__back { border: 1px solid var(--hq-line2); background: var(--hq-panel); color: var(--hq-soft);
  border-radius: 10px; width: 34px; height: 30px; display: grid; place-items: center; flex: none; }
.hq-head__back:hover { color: var(--hq-bright); border-color: var(--hq-teal); }
.hq-sub { margin: 0; font-size: 13px; color: var(--hq-soft); line-height: 1.5; max-width: 640px; }
.hq-btn-ghost { background: var(--hq-panel); border: 1px solid var(--hq-line2); color: var(--hq-bright); }
.hq-btn-ghost:hover { border-color: var(--hq-teal); }
/* the irreversible actions (Elimina cliente): quiet by default — red text on a hairline, never a
   big red slab — so the destructive button can't be mistaken for the primary one. */
.hq-btn-danger { background: transparent; border: 1px solid rgba(196, 71, 58, .45); color: #d4574a; }
.hq-btn-danger:hover { background: rgba(196, 71, 58, .1); border-color: #c4473a; }
.hq-btn-danger:disabled { opacity: .45; }
.hq-modal__panel [data-typed] { width: 100%; margin: -4px 0 14px; }
.hq .su-card { background: var(--hq-panel); border: 1px solid var(--hq-line2); border-radius: 16px; }
.hq .su-card__icon { border-color: var(--hq-line2); }
.hq .su-card__name { color: var(--hq-bright); }
.hq .su-card__vert, .hq .muted, .hq .mono { color: var(--hq-soft); }
.hq .chip { background: var(--hq-panel2); border: 1px solid var(--hq-line2); color: var(--hq-soft); }
.hq .su-edit { border-top-color: var(--hq-line2); }
.hq .su-field > label { color: var(--hq-soft); }
.hq .su-logo { border-color: var(--hq-line2); }
.hq .su-logo.is-drop { border-color: var(--hq-teal); }
.hq .su-edit input[type="color"] { border-color: var(--hq-line2); background: var(--hq-panel); }

/* ---- HQ language pill (EN default | IT), mirroring the marketing pages' langseg ---- */
.hq-langseg { display: inline-flex; background: var(--hq-panel); border: 1px solid var(--hq-line2);
  border-radius: 999px; overflow: hidden; flex: none; }
.hq-langseg button { background: transparent; border: none; color: var(--hq-soft); font: inherit;
  font-size: 11px; font-weight: 700; padding: 5px 10px; cursor: pointer; letter-spacing: .04em; }
.hq-langseg button.on { background: var(--hq-teal); color: #fff; }
.hqgate__lang { display: flex; justify-content: center; margin-bottom: 4px; }

/* ---- HQ real brand (Tony, 2026-07-16): the actual Telaio icon + Sora wordmark everywhere the
   name appears. "HQ" is set in real Sora (a 716-byte self-hosted subset of just H+Q — same
   self-host+no-CDN rule as every other font here). ---- */
@font-face {
  font-family: 'Sora HQ';
  src: url('../assets/fonts/sora-700-hq.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: block;
}
.hq-brandmark { height: 72px; width: auto; display: block; margin: 0 auto 2px; }
.hq-brandline { display: flex; align-items: center; justify-content: center; gap: 5px; margin: 0; }
.hq-brandline img { height: 24px; width: auto; display: block; }
.hq-hq { font-family: 'Sora HQ', 'Avenir Next', -apple-system, sans-serif; font-weight: 700;
  font-size: 29px; line-height: 1; color: var(--hq-teal); letter-spacing: .01em; }
.hq-head__brand { display: flex; align-items: center; gap: 4px; }
.hq-head__brand img { height: 30px; width: auto; display: block; }
.hq-head__brand .hq-hq { font-size: 20px; }

/* Narrow phones: keep the HQ header on ONE line (brand + pill + email + esci all shrink politely) */
@media (max-width: 480px) {
  .hq-head { gap: 7px; }
  .hq-head__brand img { height: 24px; }
  .hq-head__brand .hq-hq { font-size: 18px; }
  .hq-head__who { max-width: 28vw; font-size: 10.5px; }
}

/* ---- HQ · Clienti & Visite + Codici Fondatori (2026-07-16) ---- */
.hq-chiprow { display: flex; gap: 7px; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
.hq-chiprow::-webkit-scrollbar { display: none; }
.hq-chip { flex: none; border: 1px solid var(--hq-line2); background: var(--hq-panel); color: var(--hq-soft);
  font: inherit; font-size: 12px; font-weight: 650; border-radius: 999px; padding: 6px 12px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hq-chip.on { background: var(--hq-teal); border-color: var(--hq-teal); color: #fff; }
.hq-list { display: flex; flex-direction: column; gap: 8px; }
.hq-row { display: flex; align-items: center; gap: 11px; background: var(--hq-panel); border: 1px solid var(--hq-line);
  border-radius: 13px; padding: 10px 12px; text-decoration: none; color: inherit; }
.hq-row__tx { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.hq-row__tx b { font-size: 15px; font-weight: 700; color: var(--hq-bright); line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hq-row, .hq-row a, .hq-row b { -webkit-tap-highlight-color: transparent; }
.hq-row, .hq-row:visited, .hq-row:active, .hq-row:hover,
.hq-row a, .hq-row a:visited, .hq-row a:active, .hq-row a:hover { text-decoration: none !important; }
.hq-row__tx a { display: block; min-width: 0; max-width: 100%; }
.hq-row__tx b { max-width: 100%; }
.hq-row__tx a { color: inherit; text-decoration: none; }
.hq-row__tx > span { font-size: 12px; color: var(--hq-soft); }
.hq-ph { width: 46px; height: 46px; border-radius: 11px; object-fit: cover; flex: none; border: 1px solid var(--hq-line2); }
.hq-ph--empty { display: grid; place-items: center; color: var(--hq-soft); background: var(--hq-panel2); }
.hq-ph--big { width: 76px; height: 76px; border-radius: 15px; cursor: zoom-in; }
.hq-stage { flex: none; font-size: 10.5px; font-weight: 700; border-radius: 999px; padding: 4px 9px; white-space: nowrap;
  color: var(--hq-soft); border: 1px solid var(--hq-line2); }
.hq-stage--attivato { color: #14110a; background: var(--hq-gold); border-color: var(--hq-gold); }
.hq-stage--cliente { color: var(--hq-good); border-color: rgba(75, 185, 138, .4); background: rgba(75, 185, 138, .08); }
.hq-stage--codice_consegnato { color: var(--hq-teal); border-color: rgba(42, 165, 149, .45); background: rgba(42, 165, 149, .09); }
.hq-stage--perso { color: #c4473a; border-color: rgba(196, 71, 58, .45); background: rgba(196, 71, 58, .08); }

/* ---- client status chip: WHERE a venue stands, in one glance ----------------------------------
   Four states along one journey, so the colour PROGRESSES: grey (nothing yet) → amber (built, not
   live) → teal (live) → green (live AND the owner runs it = finished). Same shape/size as .hq-stage
   so the two lists stay one family. The legend below the list spells each one out. */
.hq-cst { flex: none; font-size: 10.5px; font-weight: 700; border-radius: 999px; padding: 4px 9px; white-space: nowrap;
  color: var(--hq-soft); border: 1px solid var(--hq-line2); background: transparent; }
.hq-cst--bozza { color: var(--hq-gold); border-color: color-mix(in srgb, var(--hq-gold) 45%, transparent); background: color-mix(in srgb, var(--hq-gold) 9%, transparent); }
.hq-cst--online { color: var(--hq-teal); border-color: rgba(42, 165, 149, .45); background: rgba(42, 165, 149, .09); }
.hq-cst--attivo { color: var(--hq-good); border-color: rgba(75, 185, 138, .45); background: rgba(75, 185, 138, .1); }
/* The two closed-account states. They break the journey's colour progression on purpose: this is
   not a further step along the same path, it is the path ending — and 'dacanc' is the only chip in
   HQ that means "a legal obligation is waiting on you". */
.hq-cst--chiuso { color: var(--hq-soft); border-color: var(--hq-line2); background: rgba(255, 255, 255, .04); }
.hq-cst--dacanc { color: #f0a49d; border-color: rgba(224, 122, 114, .5); background: rgba(224, 122, 114, .12); }

/* No legend: the labels say what they mean ("Bozza App", "Manager Attivo"). A longer label needs the
   row's TEXT to give way, not the chip — so the text column shrinks/ellipsises and the chip stays whole. */
.hq-row .hq-cst { max-width: 45%; overflow: hidden; text-overflow: ellipsis; }
.hq-stars { display: inline-flex; gap: 2px; }
.hq-stars svg { stroke: var(--hq-gold); }
.hq-stars svg.on { fill: var(--hq-gold); }
.hq-stars--edit { gap: 7px; margin-top: 3px; }
.hq-stars--edit svg { cursor: pointer; }
.hq-scorelbl { font-size: 11px; color: var(--hq-soft); margin-top: 7px; }
.hq-idrow { display: flex; gap: 13px; align-items: flex-start; }
.hq-idtx { display: flex; flex-direction: column; min-width: 0; }
.hq-idtx > b { font-size: 21px; font-weight: 800; color: var(--hq-bright); letter-spacing: -.01em; line-height: 1.15; }
.hq-idtx > span { font-size: 12.5px; color: var(--hq-soft); display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 3px; }
.hq-banner { background: var(--hq-panel); border: 1px solid var(--hq-line2); border-radius: 13px; padding: 12px 14px;
  font-size: 14px; color: var(--hq-ink); }
.hq-banner b { color: var(--hq-bright); font-variant-numeric: tabular-nums; }
.hq-banner--gold { background: linear-gradient(150deg, rgba(243, 177, 75, .16), rgba(243, 177, 75, .06));
  border-color: rgba(243, 177, 75, .4); color: var(--hq-cream); }
.hq-banner--gold b { color: var(--hq-gold); }
.hq-banner--good { border-color: rgba(75, 185, 138, .4); background: rgba(75, 185, 138, .08); color: var(--hq-good); }
/* The account the owner CLOSED and whose 30 days are up — his photos and his login are still alive
   and only a human can remove them. The one banner in HQ that means "act now", so it is the only
   one that reads as an alarm rather than a note. */
.hq-banner--danger { border-color: rgba(224, 122, 114, .5); background: rgba(224, 122, 114, .1); color: #f0a49d; }
.hq-actrow { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.hq-actrow .btn:only-child { grid-column: 1 / -1; }
.hq-card { background: var(--hq-panel); border: 1px solid var(--hq-line); border-radius: 13px; padding: 8px 13px 11px;
  display: flex; flex-direction: column; gap: 2px; }
.hq-crow { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--hq-ink); padding: 6px 0;
  border-bottom: 1px solid var(--hq-line); }
.hq-crow:last-of-type { border-bottom: none; }
.hq-crow svg { color: var(--hq-teal); flex: none; }
.hq-crow a { color: var(--hq-bright); text-decoration: none; }
.hq-crow__wa { margin-left: auto; flex: none; }
.hq-crow__wa svg { color: inherit; }
.hq-missing { color: var(--hq-soft); font-style: italic; }
.hq-tag { margin-left: auto; font-size: 10px; font-weight: 700; color: var(--hq-gold);
  border: 1px solid rgba(243, 177, 75, .4); border-radius: 999px; padding: 3px 8px; white-space: nowrap; }
.hq-card .btn { align-self: stretch; margin-top: 10px; }
.hq-form { display: flex; flex-direction: column; gap: 10px; }
.hq-photo-add { display: flex; align-items: center; gap: 11px; font-size: 13.5px; color: var(--hq-soft); cursor: pointer; }
.hq-tl { display: flex; flex-direction: column; padding: 2px 4px; }
.hq-ev { display: flex; gap: 10px; font-size: 12.5px; color: var(--hq-soft); padding: 3px 0; }
.hq-ev span { color: var(--hq-gold); font-variant-numeric: tabular-nums; width: 52px; flex: none; }
.hq-ev b { color: var(--hq-ink); font-weight: 650; }
.hq-ev i { font-style: normal; color: var(--hq-soft); }
.hq-del { align-self: stretch; width: 100%; border: 1px solid rgba(196, 71, 58, .5); border-radius: 11px;
  background: rgba(196, 71, 58, .08); color: #e07a72; font: inherit; font-size: 14.5px; font-weight: 700;
  padding: 12px 10px; cursor: pointer; margin-top: 6px; -webkit-tap-highlight-color: transparent; }
.hq-del:hover { background: rgba(196, 71, 58, .16); }
/* replaces "Elimina locale" while the venue still has an app — a NOTICE, not a dead button: gold text
   + the house "read this before you act" triangle, on a gold-tinted hairline. Deliberately not a
   filled slab — it sits on every client card that has an app, permanently, so it has to stay quiet
   enough to live there without shouting, while still catching the eye when you go looking to delete. */
.hq-del-blocked { display: flex; align-items: flex-start; gap: 9px; margin: 0; padding: 11px 13px;
  border: 1px dashed color-mix(in srgb, var(--hq-gold) 55%, transparent); border-radius: 11px;
  background: color-mix(in srgb, var(--hq-gold) 7%, transparent);
  font-size: 12.5px; line-height: 1.45; color: var(--hq-gold); text-align: left; }
.hq-del-blocked i { flex: none; font-size: 17px; line-height: 1.25; }
.hq-modal { position: fixed; inset: 0; z-index: 1000; background: rgba(0, 0, 0, .6); display: grid; place-items: center; padding: 24px; }
.hq-modal__panel { width: 100%; max-width: 340px; background: #1a1d1b; border: 1px solid var(--hq-line2); border-radius: 16px;
  padding: 20px 18px 16px; color: var(--hq-ink); box-shadow: 0 30px 70px rgba(0, 0, 0, .55); }
.hq-modal__panel p { margin: 0 0 16px; font-size: 14px; line-height: 1.5; }
.hq-modal__row { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.hq-row--code .hq-code { font-weight: 800; font-size: 14.5px; color: var(--hq-cream); font-variant-numeric: tabular-nums; min-width: 62px; flex: none; }
.hq-code--dead { text-decoration: line-through; color: var(--hq-soft); }
.hq-fchip { flex: none; font-size: 11px; font-weight: 700; border-radius: 999px; padding: 4px 9px; white-space: nowrap;
  color: var(--hq-soft); border: 1px solid var(--hq-line2); font-variant-numeric: tabular-nums; }
.hq-fchip--gold { color: #14110a; background: var(--hq-gold); border-color: var(--hq-gold); }
.hq-fchip--good { color: var(--hq-good); border-color: rgba(75, 185, 138, .4); background: rgba(75, 185, 138, .08); }
.hq-fchip--dead { color: #c4473a; border-color: rgba(196, 71, 58, .45); background: rgba(196, 71, 58, .08); }
.hq-wabtn { border: 1px solid var(--hq-line2); background: #1c201d; color: var(--hq-teal); border-radius: 10px;
  width: 36px; height: 36px; display: grid; place-items: center; cursor: pointer; flex: none; padding: 0; }
.hq-wabtn .ti { line-height: 1; display: block; }  /* the icon FONT has a baseline — kill it or the glyph sits low */
/* The recovery-saga lesson, applied to HQ: display:flex/grid on a class DEFEATS the hidden
   attribute — make [hidden] win everywhere inside .hq. */
.hq [hidden] { display: none !important; }
.hq-btn-gold { background: var(--hq-gold); color: #14110a; border: none; font-weight: 700; }
.hq-btn-gold:hover { filter: brightness(1.06); }
.hq-remswitch { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.hq-remswitch > span { display: flex; align-items: center; gap: 8px; color: var(--hq-bright); font-weight: 650; }
.hq-remswitch svg { color: var(--hq-teal); }
.hq-row--due { border-color: rgba(243, 177, 75, .45); }
.hq-tile__dot { position: absolute; top: 11px; right: 11px; min-width: 22px; height: 22px; border-radius: 999px;
  background: #e0453a; color: #fff; font-size: 12px; font-weight: 800; display: grid; place-items: center;
  padding: 0 6px; font-variant-numeric: tabular-nums; box-shadow: 0 2px 8px rgba(0, 0, 0, .4); }

/* ---- HQ · Nuovo Cliente wizard (block 1, 2026-07-16) ---- */
.hq-steps { display: flex; gap: 6px; flex-wrap: wrap; }
.hq-step { font-size: 11.5px; font-weight: 700; color: var(--hq-soft); background: var(--hq-panel);
  border: 1px solid var(--hq-line); border-radius: 999px; padding: 5px 11px; }
.hq-step.on { color: #14110a; background: var(--hq-gold); border-color: var(--hq-gold); }
.hq-step.done { color: var(--hq-teal); border-color: rgba(42, 165, 149, .45); }
.hq-lbl { margin: 4px 2px -4px; font-size: 11px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--hq-soft); }
.hq-nw-note { font-style: normal; text-transform: none; letter-spacing: 0; font-weight: 500; opacity: .8; }
.hq-tpl { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.hq-tpl__t { position: relative; display: flex; flex-direction: column; gap: 3px; text-align: left;
  background: var(--hq-panel); border: 1px solid var(--hq-line2); border-radius: 13px; padding: 13px 12px;
  font-family: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hq-tpl__t b { font-size: 15px; font-weight: 700; color: var(--hq-bright); }
.hq-tpl__t span { font-size: 11.5px; color: var(--hq-soft); line-height: 1.35; }
.hq-tpl__t.sel { border-color: var(--hq-teal); background: rgba(42, 165, 149, .1); }
.hq-tpl__t.sel::after { content: "✓"; position: absolute; top: 10px; right: 12px; color: var(--hq-teal); font-weight: 800; }
.hq-tpl__t.soon { opacity: .45; cursor: default; }
.hq-tpl__t.soon i { position: absolute; top: 9px; right: 9px; font-style: normal; font-size: 10px;
  font-weight: 700; color: var(--hq-soft); border: 1px solid var(--hq-line2); border-radius: 999px; padding: 2px 7px; }
.hq-nw-slugrow { display: flex; align-items: center; gap: 8px; }
.hq-nw-slugrow .input { flex: 1; min-width: 0; }
.hq-nw-slugrow > span { font-size: 13px; color: var(--hq-soft); white-space: nowrap; }
.hq-nw-slugmsg { margin: 5px 2px 0; font-size: 12px; color: var(--hq-soft); min-height: 1em; }
.hq-nw-slugmsg.ok { color: var(--hq-good); }
.hq-nw-slugmsg.bad { color: #e08578; }
.brand-rowx { display: flex; align-items: center; gap: 12px; background: var(--hq-panel);
  border: 1px solid var(--hq-line); border-radius: 13px; padding: 11px 13px; }
.brand-rowx input[type="color"] { width: 44px; height: 40px; padding: 2px; border: 1px solid var(--hq-line2);
  border-radius: 10px; background: var(--hq-panel2); cursor: pointer; flex: none; }
.brand-rowx b { font-size: 13px; color: var(--hq-bright); }
.hq-nw-hex { max-width: 120px; margin-top: 4px; padding: 6px 9px; font-size: 13px; }
.hq-wardrobe { display: flex; flex-direction: column; gap: 8px; }
.hq-wardrobe__f { display: flex; flex-direction: column; gap: 2px; text-align: left; background: var(--hq-panel);
  border: 1px solid var(--hq-line2); border-radius: 13px; padding: 11px 13px; font-family: inherit;
  color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hq-wardrobe__f b { font-size: 20px; font-weight: 600; color: var(--hq-bright); line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hq-wardrobe__f span { font-size: 11px; color: var(--hq-soft); }
.hq-wardrobe__f.sel { border-color: var(--hq-teal); background: rgba(42, 165, 149, .1); }
.hq-nw-preview { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center;
  background: var(--hq-panel); border: 1px solid var(--hq-line2); border-radius: 16px; padding: 18px 14px; }
.hq-nw-preview img { max-height: 64px; max-width: 70%; object-fit: contain; }
.hq-nw-preview > b { font-size: 24px; color: var(--hq-bright); }
.hq-nw-preview > span { font-size: 12px; color: var(--hq-soft); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: center; }
.hq-nw-sw { display: inline-block; width: 13px; height: 13px; border-radius: 4px; background: var(--c); border: 1px solid rgba(255,255,255,.2); }
.hq-nw-addr { font-size: 15px; font-weight: 800; color: var(--hq-teal); font-variant-numeric: tabular-nums; }
.hq-nw-addr i { font-style: normal; color: var(--hq-soft); font-weight: 600; }
.hq-nw-wdlink { font-size: 12px; color: var(--hq-soft); text-decoration: none; align-self: flex-start; padding: 2px; }
.hq-nw-wdlink:active { color: var(--hq-teal); }

/* The app-icon preview: the logo exactly as it will sit in the icon square (signature colour bg) */
.hq-iconrow { display: flex; align-items: center; gap: 14px; }
.hq-iconprev { width: 84px; height: 84px; flex: none; border-radius: 19px; background: var(--c);
  border: 1px solid rgba(255, 255, 255, .12); display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35); }
/* 90% content (Tony, 2026-07-17: 66% read too small) — matches the shipped iOS/any icons;
   Android circle masks get their own separately-baked 62% variant, so nothing ever clips. */
.hq-iconprev img { max-width: 90%; max-height: 90%; object-fit: contain; }
/* No logo → the monogram the icon factory actually bakes (white, serif, same 44%-of-the-square
   proportion as makeIconSet) — the preview must not flatter what the phone will really show. */
.hq-iconprev__mono { font-family: Georgia, serif; font-weight: 600; font-size: 37px; color: #fff; line-height: 1; }
.hq-iconwrap { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: none; }
.hq-iconprev__lbl { font-size: 11px; color: var(--hq-bright); max-width: 88px; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: 1em; }
.hq-iconrow__tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.hq-iconrow__tx b { font-size: 13px; color: var(--hq-bright); }
.hq-iconrow__tx > span { font-size: 11.5px; color: var(--hq-soft); line-height: 1.35; }
.hq-iconrow__crop { align-self: flex-start; margin-top: 5px; padding: 7px 16px; font-size: 13px; }
/* "Ritaglia" on a logo row — same weight as the one that used to sit under the Icona App, so
   moving it reads as the same button in a better place, not a new one. */
.hq-logotile__crop { align-self: flex-start; margin-top: 6px; padding: 6px 15px; font-size: 12.5px; }
/* The client's "face" once his app exists: the icon itself (logo on the signature colour) */
/* A label+input+note group inside a form: restores the form's own rhythm (the bare wrapper
   div was collapsing it, leaving the label glued to its field). */
.hq-fieldblock { display: flex; flex-direction: column; gap: 10px; margin-top: 6px; }
/* Two colour pickers on one row: Colore firma | Colore background (Tony, 2026-07-17) */
.hq-colrow { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.hq-colrow .brand-rowx { min-width: 0; }
.hq-colrow .hq-nw-hex { max-width: 100%; }
.hq-sep { border: none; border-top: 1px solid var(--hq-line2); margin: 2px 0; }

/* Logo TILES (Tony 2026-07-17): each logo judged like the Icona App — a square mini-header
   preview: Colore background ground, the logo whole, the Colore firma rule at the bottom. */
.hq-logotile { display: flex; align-items: center; gap: 14px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hq-logotile__sq { position: relative; width: 84px; height: 84px; flex: none; border-radius: 19px;
  background: var(--bg); border: 1px solid rgba(255, 255, 255, .12); display: flex; align-items: center;
  justify-content: center; overflow: hidden; box-shadow: 0 4px 14px rgba(0, 0, 0, .35); }
.hq-logotile__sq img { max-width: 74%; max-height: 58%; object-fit: contain; margin-bottom: 6px; }
.hq-logotile__empty { color: rgba(255, 255, 255, .45); margin-bottom: 6px; }
.hq-logotile__rule { position: absolute; left: 50%; transform: translateX(-50%); bottom: 11px;
  width: 62%; height: 2px; border-radius: 2px; background: var(--fx); }
/* The ✕ that clears a logo. INSIDE the square — the tile is overflow:hidden, so a badge hanging off
   the corner would be sliced. Deliberately modest (26px): it sits on top of a tile whose whole
   surface opens the file picker, so an oversized target would make an accidental wipe likelier than
   a deliberate one. Dark disc + hairline so it reads on a logo of any colour. */
.hq-logotile__x { position: absolute; top: 5px; right: 5px; width: 26px; height: 26px; padding: 0;
  display: grid; place-items: center; border-radius: 50%; cursor: pointer;
  background: rgba(0, 0, 0, .62); border: 1px solid rgba(255, 255, 255, .3); color: #fff;
  -webkit-tap-highlight-color: transparent; }
.hq-logotile__x:active { background: rgba(0, 0, 0, .85); transform: scale(.92); }
.hq-logotile__tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.hq-logotile__tx b { font-size: 13px; color: var(--hq-bright); }
.hq-logotile__tx > span { font-size: 11.5px; color: var(--hq-soft); line-height: 1.35; }

/* The Sfondo picker: samples of each shipped texture in a horizontal shelf; ring = chosen. */
.hq-bgrow { display: flex; gap: 10px; overflow-x: auto; padding: 2px 2px 8px; scrollbar-width: none; }
.hq-bgrow::-webkit-scrollbar { display: none; }
.hq-bgtile { flex: none; width: 62px; height: 96px; border-radius: 12px; overflow: hidden; padding: 0;
  border: 2px solid var(--hq-line2); background: var(--hq-panel2); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hq-bgtile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hq-bgtile.sel { border-color: var(--hq-gold); box-shadow: 0 0 0 2px rgba(243, 177, 75, .35); }

/* Sfondo Intensità: full art at 100%, softer toward the dark ground as it drops */
.hq-bgop { display: flex; align-items: center; gap: 12px; }
.hq-bgop > span { font-size: 12px; color: var(--hq-soft); flex: none; }
.hq-bgop input[type="range"] { flex: 1; accent-color: var(--hq-teal); min-width: 0; }
.hq-bgop b { font-size: 13px; color: var(--hq-bright); font-variant-numeric: tabular-nums; flex: none; width: 44px; text-align: right; }

/* The wardrobe as a DROPDOWN: closed = only the chosen face + a chevron; tap to open. */
.hq-wardrobe--closed .hq-wardrobe__f:not(.sel) { display: none; }
.hq-wardrobe--closed .hq-wardrobe__f.sel { position: relative; }
.hq-wardrobe--closed .hq-wardrobe__f.sel::after { content: '⌄'; position: absolute; right: 14px; top: 50%;
  transform: translateY(-60%); font-size: 18px; color: var(--hq-soft); }

/* the living dots of the "sto lavorando" overlay */
.hq-dots i { font-style: normal; animation: hq-dot 1.2s infinite; }
.hq-dots i:nth-child(2) { animation-delay: .2s; }
.hq-dots i:nth-child(3) { animation-delay: .4s; }
@keyframes hq-dot { 0%, 60%, 100% { opacity: .25; } 30% { opacity: 1; } }
.hq-icontile { background: var(--c); display: flex; align-items: center; justify-content: center; }
.hq-icontile img { max-width: 90%; max-height: 90%; object-fit: contain; }

/* Clienti list rows: the app address line under the name */
.hq-row__app { font-size: 12px; font-weight: 700; color: var(--hq-teal); }
.hq-row__app i { font-style: normal; color: var(--hq-soft); font-weight: 600; }
.hq-row__app.none { color: var(--hq-soft); font-weight: 500; font-style: italic; }

/* "La sua app" on the client card */
.hq-appcard { gap: 10px; }
.hq-appcard__id { display: flex; flex-direction: column; align-items: center; gap: 5px; text-align: center; padding: 6px 0 2px; }
.hq-appcard__id img { max-height: 56px; max-width: 65%; object-fit: contain; }
.hq-appcard__id > b { font-size: 22px; color: var(--hq-bright); }
.hq-appcard__id > span { font-size: 12px; color: var(--hq-soft); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: center; }
/* The ADDRESS is not one of the little detail lines above, but the `> span` rule caught it too:
   the 6px flex gap opened a space in the middle of the address ("testlab2 .studiocorocher.com")
   and the 12px grey washed out the one line on this card that is the actual product. It keeps its
   own identity here, and it's a real link once the app is live. */
.hq-appcard__id > .hq-nw-addr { display: block; font-size: 15px; color: var(--hq-teal); text-decoration: none; }
.hq-appst { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 99px; }
.hq-appst--bozza { color: var(--hq-gold); background: rgba(212, 160, 55, .12); border: 1px solid rgba(212, 160, 55, .35); }
.hq-appst--provisioning { color: var(--hq-soft); background: rgba(255, 255, 255, .06); border: 1px solid var(--hq-line2); }
/* double class = outranks the .hq-appcard__id > span colour/size (it was washing the text grey) */
.hq-appst.hq-appst--live { color: #14110a; background: var(--hq-gold); border: 1px solid var(--hq-gold);
  font-size: 14px; font-weight: 800; padding: 7px 18px; letter-spacing: .02em; }
/* the whole panel celebrates: an ONLINE app is the product, delivered */
.hq-appcard--live { border-color: rgba(243, 177, 75, .5); background: rgba(243, 177, 75, .05);
  box-shadow: 0 0 0 1px rgba(243, 177, 75, .12), 0 6px 22px rgba(0, 0, 0, .25); }

/* The MANAGER chapter — "his login" block on the live card, + the credentials result sheet */
.hq-mgr { display: flex; flex-direction: column; gap: 8px; padding-top: 11px; margin-top: 3px; border-top: 1px solid var(--hq-line2); }
.hq-mgr .hq-lbl { margin: 0; }
.hq-mgr-done { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 700; color: var(--hq-good); }
.hq-mgr-done span { color: var(--hq-soft); font-weight: 500; word-break: break-all; }
/* "Reimposta password" — the quiet rescue under the green line. Deliberately NOT gold (gold is the
   create action) and NOT red (red is delete): a small, calm, self-sized button, left-aligned. */
.hq-mgr-reset { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; padding: 7px 12px; }
.hq-modal__panel .hq-mgr-title { font-size: 17px; font-weight: 800; color: var(--hq-bright); text-align: center; margin: 0 0 14px; }
.hq-sub--warn { color: var(--hq-bright); background: rgba(243, 177, 75, .1);
  border: 1px solid rgba(243, 177, 75, .35); border-radius: 9px; padding: 8px 10px; margin-top: 10px; }
.hq-cred { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--hq-line2); }
.hq-cred span { font-size: 12px; color: var(--hq-soft); flex-shrink: 0; }
.hq-cred b { font-size: 14px; color: var(--hq-bright); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; text-align: right; word-break: break-all; }
.hq-cred:last-of-type { border-bottom: none; }

/* Font wardrobe showcase (#/hq/font) */
.hq-wd { display: flex; flex-direction: column; gap: 10px; }
.hq-wd__f { position: relative; display: flex; flex-direction: column; gap: 3px; text-align: left; background: var(--hq-panel);
  border: 1px solid var(--hq-line2); border-radius: 15px; padding: 16px 15px 13px; font-family: inherit;
  color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hq-wd__f b { font-size: 27px; font-weight: 600; color: var(--hq-bright); line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hq-wd__f span { font-size: 11px; color: var(--hq-soft); }
.hq-wd__f i { font-style: normal; font-size: 11px; font-weight: 700; color: var(--hq-soft); margin-top: 4px; }
.hq-wd__f.on { border-color: var(--hq-gold); background: rgba(212, 160, 55, .07); }
.hq-wd__f.on i { color: var(--hq-gold); }
