/* ============================================================================
   docTOrius — direction "Notte"
   Dark, calm, premium. A dark ground makes the few things that matter glow:
   availability, the week bar, one primary action per card.

   Everything is expressed as tokens so a light theme is a token swap rather
   than a rewrite. The design commits to dark for now, so `color-scheme: dark`
   is declared and every colour is painted explicitly.
   ========================================================================== */
:root {
  color-scheme: dark;

  --gutter: 22px;

  --bg:        #0D0F13;
  --surf:      #161A20;
  --surf-2:    #1E232B;
  --surf-3:    #2A313A;
  --ink:       #EDEFF2;
  --ink-2:     #A8B0BA;
  --muted:     #79828E;
  --faint:     #5A636E;
  --line:      rgba(255, 255, 255, 0.08);
  --line-2:    rgba(255, 255, 255, 0.14);

  --honey:     #E9A648;
  --honey-ink: #241804;
  --honey-dim: rgba(233, 166, 72, 0.13);
  --mint:      #59C9A5;
  --mint-dim:  rgba(89, 201, 165, 0.14);
  --rose:      #E8735F;
  --rose-dim:  rgba(232, 115, 95, 0.14);
  /* Distinct from --honey (used for the MMG badge right next to it): the "in my round" star
     needs to read as its own signal, not a second orange blur. */
  --gold:      #F2CB4E;
  --gold-dim:  rgba(242, 203, 78, 0.15);
  --sky:       #6FA8DC;
  --sky-dim:   rgba(111, 168, 220, 0.15);

  /* One hand-picked color per specialty code (see DoctorPresentation.TipologiaBadgeClass) —
     there is no industry-standard palette for these, they are the rep's own shorthand. */
  --pink:      #E06FB0;
  --pink-dim:  rgba(224, 111, 176, 0.15);
  --coral:     #E8608A;
  --coral-dim: rgba(232, 96, 138, 0.15);
  --violet:    #A78BFA;
  --violet-dim: rgba(167, 139, 250, 0.15);
  --tan:       #C08A5B;
  --tan-dim:   rgba(192, 138, 91, 0.15);
  --slate:     #8FA6C2;
  --slate-dim: rgba(143, 166, 194, 0.15);
  --magenta:   #C85FC0;
  --magenta-dim: rgba(200, 95, 192, 0.15);
  --olive:     #B3C24C;
  --olive-dim: rgba(179, 194, 76, 0.15);
  --teal:      #3FBFA8;
  --teal-dim:  rgba(63, 191, 168, 0.15);
  --cyan:      #4FC6D9;
  --cyan-dim:  rgba(79, 198, 217, 0.15);
  --indigo:    #8C7AE0;
  --indigo-dim: rgba(140, 122, 224, 0.15);
  /* Le strutture (ospedali, cliniche) non sono una specialita' in piu': sono un'altra cosa,
     e questo grigio-azzurro istituzionale le stacca da tutte le tinte dei medici. */
  --steel:     #8FB3C9;
  --steel-dim: rgba(143, 179, 201, 0.15);

  --r-sm: 8px;
  --r-md: 11px;
  --r-lg: 16px;
  --r-xl: 20px;

  --sans: "Familjen Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --shadow-card: 0 1px 0 rgba(255, 255, 255, 0.045) inset, 0 14px 34px -22px rgba(0, 0, 0, 0.9);

  /* Overlays and shadows, tokenised so day mode is a swap rather than a second stylesheet.
     A white wash lifts a surface on a dark ground; on paper the same job needs an ink wash. */
  --wash-soft: rgba(255, 255, 255, 0.035);
  --wash:      rgba(255, 255, 255, 0.055);
  --wash-2:    rgba(255, 255, 255, 0.08);
  --wash-3:    rgba(255, 255, 255, 0.10);
  --track:     rgba(255, 255, 255, 0.09);
  --shimmer:   rgba(255, 255, 255, 0.05);

  --appbar-bg:     rgba(13, 15, 19, 0.92);
  --backdrop:      rgba(6, 8, 11, 0.72);
  --ring:          rgba(0, 0, 0, 0.28);
  --honey-hover:   #F2B65E;
  --shadow-menu:   0 18px 40px -16px rgba(0, 0, 0, 0.9);
  --shadow-pop:    0 26px 60px -20px rgba(0, 0, 0, 0.9);
  --shadow-pop-sm: 0 16px 34px -14px rgba(0, 0, 0, 0.85);
}

/* ============================================================================
   Direction "Giorno" — the same design in daylight.

   Not an inversion: the honey accent is deepened so it still reads as text on
   paper, the washes become ink rather than white, and the shadows lose the
   near-black opacity that only works on a dark ground. Everything else is the
   same stylesheet.

   Three states, because ThemeMode has three: an explicit choice stamps
   data-theme, and the default "system" stamps nothing and follows the device.
   ========================================================================== */
:root[data-theme="light"] {
  color-scheme: light;

  --bg:        #F7F5F1;
  --surf:      #FFFFFF;
  --surf-2:    #F1EEE8;
  --surf-3:    #E6E1D8;
  --ink:       #15181D;
  --ink-2:     #454D57;
  --muted:     #6B747E;
  --faint:     #9AA2AB;
  --line:      rgba(20, 24, 30, 0.11);
  --line-2:    rgba(20, 24, 30, 0.18);

  /* Deepened so it passes as body text and as a link on white; the buttons that
     use it as a background take the light ink instead. */
  --honey:     #B77A17;
  --honey-ink: #FFF8EC;
  --honey-dim: rgba(183, 122, 23, 0.12);
  --mint:      #2F8F6F;
  --mint-dim:  rgba(47, 143, 111, 0.14);
  --rose:      #C2503C;
  --rose-dim:  rgba(194, 80, 60, 0.14);
  --gold:      #C9A227;
  --gold-dim:  rgba(201, 162, 39, 0.15);
  --sky:       #3E71A8;
  --sky-dim:   rgba(62, 113, 168, 0.13);
  --pink:      #B84A88;
  --pink-dim:  rgba(184, 74, 136, 0.13);
  --coral:     #C23F68;
  --coral-dim: rgba(194, 63, 104, 0.13);
  --violet:    #7C5CE0;
  --violet-dim: rgba(124, 92, 224, 0.13);
  --tan:       #8A5A2E;
  --tan-dim:   rgba(138, 90, 46, 0.13);
  --slate:     #5A7391;
  --slate-dim: rgba(90, 115, 145, 0.13);
  --magenta:   #964090;
  --magenta-dim: rgba(150, 64, 144, 0.13);
  --olive:     #7D8A2E;
  --olive-dim: rgba(125, 138, 46, 0.13);
  --teal:      #217A69;
  --teal-dim:  rgba(33, 122, 105, 0.13);
  --cyan:      #1F8A9C;
  --cyan-dim:  rgba(31, 138, 156, 0.13);
  --indigo:    #5F4BC4;
  --indigo-dim: rgba(95, 75, 196, 0.13);
  --steel:     #3D6C8A;
  --steel-dim: rgba(61, 108, 138, 0.13);

  --shadow-card: 0 1px 2px rgba(20, 24, 30, 0.06);

  --wash-soft: rgba(20, 24, 30, 0.028);
  --wash:      rgba(20, 24, 30, 0.045);
  --wash-2:    rgba(20, 24, 30, 0.075);
  --wash-3:    rgba(20, 24, 30, 0.10);
  --track:     rgba(20, 24, 30, 0.10);
  --shimmer:   rgba(20, 24, 30, 0.05);

  --appbar-bg:     rgba(247, 245, 241, 0.92);
  --backdrop:      rgba(20, 24, 30, 0.42);
  --ring:          rgba(20, 24, 30, 0.16);
  --honey-hover:   #A56B12;
  --shadow-menu:   0 18px 40px -18px rgba(20, 24, 30, 0.26);
  --shadow-pop:    0 26px 60px -22px rgba(20, 24, 30, 0.28);
  --shadow-pop-sm: 0 16px 34px -16px rgba(20, 24, 30, 0.22);
}



@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;

    --bg:        #F7F5F1;
    --surf:      #FFFFFF;
    --surf-2:    #F1EEE8;
    --surf-3:    #E6E1D8;
    --ink:       #15181D;
    --ink-2:     #454D57;
    --muted:     #6B747E;
    --faint:     #9AA2AB;
    --line:      rgba(20, 24, 30, 0.11);
    --line-2:    rgba(20, 24, 30, 0.18);

    --honey:     #B77A17;
    --honey-ink: #FFF8EC;
    --honey-dim: rgba(183, 122, 23, 0.12);
    --mint:      #2F8F6F;
    --mint-dim:  rgba(47, 143, 111, 0.14);
    --rose:      #C2503C;
    --rose-dim:  rgba(194, 80, 60, 0.14);
    --gold:      #C9A227;
    --gold-dim:  rgba(201, 162, 39, 0.15);
    --sky:       #3E71A8;
    --sky-dim:   rgba(62, 113, 168, 0.13);
    --pink:      #B84A88;
    --pink-dim:  rgba(184, 74, 136, 0.13);
    --coral:     #C23F68;
    --coral-dim: rgba(194, 63, 104, 0.13);
    --violet:    #7C5CE0;
    --violet-dim: rgba(124, 92, 224, 0.13);
    --tan:       #8A5A2E;
    --tan-dim:   rgba(138, 90, 46, 0.13);
    --slate:     #5A7391;
    --slate-dim: rgba(90, 115, 145, 0.13);
    --magenta:   #964090;
    --magenta-dim: rgba(150, 64, 144, 0.13);
    --olive:     #7D8A2E;
    --olive-dim: rgba(125, 138, 46, 0.13);
    --teal:      #217A69;
    --teal-dim:  rgba(33, 122, 105, 0.13);
    --cyan:      #1F8A9C;
    --cyan-dim:  rgba(31, 138, 156, 0.13);
    --indigo:    #5F4BC4;
    --indigo-dim: rgba(95, 75, 196, 0.13);
    --steel:     #3D6C8A;
    --steel-dim: rgba(61, 108, 138, 0.13);

    --shadow-card: 0 1px 2px rgba(20, 24, 30, 0.06);

    --wash-soft: rgba(20, 24, 30, 0.028);
    --wash:      rgba(20, 24, 30, 0.045);
    --wash-2:    rgba(20, 24, 30, 0.075);
    --wash-3:    rgba(20, 24, 30, 0.10);
    --track:     rgba(20, 24, 30, 0.10);
    --shimmer:   rgba(20, 24, 30, 0.05);

    --appbar-bg:     rgba(247, 245, 241, 0.92);
    --backdrop:      rgba(20, 24, 30, 0.42);
    --ring:          rgba(20, 24, 30, 0.16);
    --honey-hover:   #A56B12;
    --shadow-menu:   0 18px 40px -18px rgba(20, 24, 30, 0.26);
    --shadow-pop:    0 26px 60px -22px rgba(20, 24, 30, 0.28);
    --shadow-pop-sm: 0 16px 34px -16px rgba(20, 24, 30, 0.22);
  }
}

/* The Google button is brand-locked: it stays white with dark text in both themes. */

* { box-sizing: border-box; }

/* The browser's own [hidden] UA rule is easily outranked by any author rule that sets display
   on the same element (a .btn's display: inline-flex, say) — !important here is what actually
   makes toggling the hidden attribute hide the thing, everywhere it's used. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 { margin: 0; letter-spacing: -0.02em; text-wrap: balance; font-weight: 600; }
p { margin: 0; }
a { color: var(--honey); text-decoration: none; }
a:hover { text-decoration: underline; }

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

/* ---------- layout ---------- */
.page { min-height: 100vh; display: flex; flex-direction: column; }
.container { width: 100%; max-width: 1120px; margin: 0 auto; padding: 0 var(--gutter); }
@media (max-width: 640px) { :root { --gutter: 18px; } }

/* Nothing should ever push the page sideways; a single overflowing child used to drag the
   sticky header out of view along with it. */
body { overflow-x: hidden; }

.appbar {
  border-bottom: 1px solid var(--line);
  background: var(--appbar-bg);
  backdrop-filter: blur(10px);
  position: sticky; top: 0; z-index: 30;
}
.appbar-inner {
  display: flex; align-items: center; gap: 12px; min-width: 0;
  /* Vertical only. Setting the padding shorthand here would override the horizontal gutter the
     .container class supplies, which is what left the logo hard against the screen edge. */
  padding-block: 11px;
}

.logo { font-weight: 700; font-size: 19px; letter-spacing: -0.03em; color: var(--ink); flex: 0 0 auto; }
.logo:hover { text-decoration: none; }
.logo em { font-style: normal; color: var(--honey); }

.nav { display: flex; gap: 3px; min-width: 0; }
.nav a {
  font-size: 13.5px; color: var(--muted); padding: 7px 12px;
  border-radius: var(--r-sm); white-space: nowrap; flex: 0 0 auto;
}
.nav a:hover { color: var(--ink); background: var(--wash); text-decoration: none; }
.nav a.active { background: var(--wash-2); color: var(--ink); }
.nav a.soon { opacity: 0.4; pointer-events: none; }
.nav-soon {
  font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.1em;
  text-transform: uppercase; margin-left: 6px; color: var(--muted);
}

.appbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

.lang { display: flex; border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; }
.lang a {
  font-size: 11.5px; font-weight: 600; padding: 6px 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.lang a:hover { color: var(--ink); text-decoration: none; }
.lang a.on { background: var(--honey); color: var(--honey-ink); }

/* ---------- header menus ---------- */
.icon-btn {
  display: grid; place-items: center; cursor: pointer; list-style: none;
  width: 36px; height: 36px; border-radius: var(--r-sm);
  border: 1px solid var(--line); background: var(--surf); color: var(--ink-2);
}
.icon-btn::-webkit-details-marker { display: none; }
.icon-btn::marker { content: ""; }
.icon-btn:hover { background: var(--surf-2); color: var(--ink); }
.icon-btn svg { width: 18px; height: 18px; }
.menu[open] > .icon-btn { background: var(--surf-2); color: var(--ink); border-color: var(--line-2); }

.menu { position: relative; }
.menu-panel {
  position: absolute; z-index: 40; top: calc(100% + 8px); right: 0;
  min-width: 208px; display: grid; gap: 2px; padding: 7px;
  /* Never wider than the screen, and never flush against its edge. */
  max-width: calc(100vw - (var(--gutter) * 2));
  background: var(--surf-2); border: 1px solid var(--line-2); border-radius: var(--r-md);
  box-shadow: var(--shadow-menu);
}
.menu-who {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); padding: 6px 11px 8px;
  border-bottom: 1px solid var(--line); margin-bottom: 4px;
}
.menu-who-account { display: flex; align-items: center; gap: 6px; }
.menu-who-account svg { flex-shrink: 0; }
.menu-lang {
  /* Hidden while the bar still shows its own language pair, so the choice appears once. */
  display: none; gap: 4px; padding: 2px 4px 8px;
  border-bottom: 1px solid var(--line); margin-bottom: 4px;
}
.menu-lang a {
  flex: 1; text-align: center; font-size: 12.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  padding: 8px 10px; border-radius: var(--r-sm);
  border: 1px solid var(--line); color: var(--muted);
}
.menu-lang a:hover { color: var(--ink); text-decoration: none; }
.menu-lang a.on { background: var(--honey); border-color: var(--honey); color: var(--honey-ink); }

.menu-divider {
  border: 0; border-top: 1px solid var(--line); margin: 4px 2px;
}

.menu-item {
  display: grid; grid-template-columns: 17px 1fr; align-items: center; gap: 11px;
  width: 100%; text-align: left;
  font-family: var(--sans); font-size: 14px; font-weight: 500; line-height: 1.3;
  padding: 10px 11px; min-height: 42px; border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--ink); cursor: pointer;
}
.menu-item > .ico { justify-self: center; }
.menu-item:hover { background: var(--wash-2); text-decoration: none; }
.menu-item .ico { width: 16px; height: 16px; flex-shrink: 0; color: var(--muted); }
.menu-item-danger { color: var(--rose); }
.menu-item-danger .ico { color: var(--rose); }
.menu-panel form { display: contents; }

.menu-panel-nav a {
  display: block; font-size: 14px; color: var(--ink);
  padding: 10px 11px 10px calc(11px + 17px + 11px);
  border-radius: var(--r-sm); white-space: nowrap;
}
.menu-panel-nav .menu-item { padding-left: 11px; }
.menu-panel-nav a:hover { background: var(--wash-2); text-decoration: none; }
.menu-panel-nav a.active { background: var(--wash-3); }
.menu-panel-nav a.soon { opacity: 0.4; pointer-events: none; }
.menu-panel-nav .menu-who { margin-top: 6px; }
.menu-panel-nav .menu-who + a { padding-left: calc(11px + 17px + 11px); }

/* The nine-dot menu duplicates links that are already inline on a wide screen. */
.apps-menu { display: none; }

@media (max-width: 860px) {
  .nav-inline { display: none; }
  .apps-menu { display: block; }
  /* Sections, language and account are all inside the one menu now. */
  .user-menu, .appbar-right > .lang { display: none; }
  .menu-lang { display: flex; }
  .logo { font-size: 18px; }
}

/* Below this the logo plus three controls no longer fit, and the overflow dragged the sticky
   header sideways — clipping the logo on one edge and the account button on the other. The
   language pair moves into the account menu, which already carries the same choice. */
@media (max-width: 560px) {
  .appbar-inner { gap: 8px; }
}

/* The account menu is the only one anchored to the right edge on a phone, so it must not
   overhang the viewport. */
@media (max-width: 420px) {
  .menu-panel { min-width: 186px; }
}

main { flex: 1; padding: 34px 0 72px; }

.page-head { margin-bottom: 26px; }
.page-head h1 { font-size: clamp(24px, 4vw, 32px); }
.page-head p { color: var(--muted); margin-top: 7px; font-size: 15px; max-width: 62ch; }

footer.foot { border-top: 1px solid var(--line); margin-top: 40px; padding: 26px 0 32px; }
.foot-inner { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.foot-inner .logo { font-size: 17px; }
.foot-inner p { font-size: 13px; color: var(--muted); }

/* ---------- controls ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--sans); font-size: 14px; font-weight: 600;
  padding: 12px 18px; min-height: 44px;
  border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--wash-soft); color: var(--ink);
  cursor: pointer; text-decoration: none; transition: background 0.15s, border-color 0.15s;
}
.btn:hover { background: var(--wash-2); text-decoration: none; }
.btn-primary { background: var(--honey); border-color: var(--honey); color: var(--honey-ink); }
.btn-primary:hover { background: var(--honey-hover); border-color: var(--honey-hover); }
.btn-danger { color: var(--rose); border-color: rgba(232, 115, 95, 0.35); }
.btn-danger:hover { background: var(--rose-dim); }
/* Solid fill, for the "yes" half of an inline confirm — the outline .btn-danger reads too close
   to a plain button next to a plain "no" one; the destructive choice needs to look like it. */
.btn-danger-fill { background: var(--rose); border-color: var(--rose); color: #fff; }
.btn-danger-fill:hover { background: #D65E49; border-color: #D65E49; }

/* Swaps a destructive button for a small "question? / si / no" row in the same spot — see
   menus.js. No box, no centering: one short red word and two small buttons, inline, the way a
   confirm reads everywhere else in this app now. */
.confirm-inline-yesno { display: inline-flex; align-items: center; gap: 7px; }
.confirm-inline-yesno span { font-size: 13px; font-weight: 700; color: var(--rose); white-space: nowrap; }
/* !important: a surrounding .doctor-card-actions gives .btn/.btn-primary their own flex-grow
   (1 and 1.4) for its own unrelated button row, and that rule happens to win on specificity —
   Sì and No must stay their own small size regardless of whichever container this lands in. */
.confirm-inline-yesno .btn {
  flex: 0 0 auto !important; min-height: 30px; padding: 5px 13px; font-size: 12.5px;
  border-radius: var(--r-sm);
}
.btn-sm { font-size: 12.5px; padding: 7px 12px; min-height: 34px; border-radius: var(--r-sm); }
.btn-block { width: 100%; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
/* A disabled .btn-primary (the "no phone number" Chiama button) faded to 45% honey still reads
   as a washed-out gold, not as off — grey it out properly instead, same size and shape. */
.btn-primary:disabled {
  background: var(--wash-2); border-color: var(--line-2); color: var(--faint); opacity: 1;
}

.field { display: grid; gap: 6px; }
.field label {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--muted);
}
.field label .opt { text-transform: none; letter-spacing: 0; font-family: var(--sans); }

/* A filter field that picks any number of values rather than one — checkboxes in a scrollable
   list, since a native multi-select is fiddly to operate (ctrl/cmd-click) and unclear at a glance
   which options are chosen. Collapsed behind a <details> disclosure by default, so a dialog with
   several of these (Brick, Tipologia, Struttura) doesn't turn into one long scroll of checkboxes. */
.filter-dropdown { border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surf); }
.filter-dropdown > summary {
  padding: 12px 14px; font-family: var(--sans); font-size: 15px; color: var(--ink);
  cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 8px;
}
.filter-dropdown > summary::-webkit-details-marker { display: none; }
.filter-dropdown > summary::marker { content: ""; }
.filter-dropdown > summary .filter-dropdown-label { color: var(--muted); font-size: 13.5px; }
.filter-dropdown > summary .chevron { width: 16px; height: 16px; color: var(--muted); transition: transform 0.15s; flex-shrink: 0; }
.filter-dropdown[open] > summary .chevron { transform: rotate(180deg); }

.checkbox-list {
  display: flex; flex-direction: column; gap: 2px; max-height: 220px; overflow-y: auto;
  padding: 8px 10px; border-top: 1px solid var(--line);
}
.checkbox-row {
  display: flex; align-items: center; gap: 9px; font-family: var(--sans); font-size: 14px;
  color: var(--ink); text-transform: none; letter-spacing: 0; padding: 5px 2px; cursor: pointer;
}
.checkbox-row input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--honey); flex-shrink: 0; }

.input {
  width: 100%; font-family: var(--sans); font-size: 15px;
  background: var(--surf); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px 14px; color: var(--ink); min-height: 46px;
}
.input::placeholder { color: var(--faint); }
.input:focus { outline: none; border-color: var(--honey); box-shadow: 0 0 0 3px var(--honey-dim); }
/* The browser's own dropdown arrow sits hard against the far edge of a wide select and looks
   stranded there — a custom one, inset the same amount on every browser, reads more deliberate. */
select.input {
  appearance: none; -webkit-appearance: none;
  padding-right: 40px;
  background-repeat: no-repeat; background-position: right 14px center; background-size: 16px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2379828E' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

/* ---------- surfaces ---------- */
.card {
  background: linear-gradient(168deg, var(--surf-2), var(--surf) 62%);
  border: 1px solid var(--line); border-radius: var(--r-xl);
  padding: 20px; box-shadow: var(--shadow-card);
}
.panel {
  background: var(--surf); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 18px;
}

.notice { border-radius: var(--r-md); padding: 12px 15px; font-size: 13.5px; border: 1px solid; }
.notice b {
  display: block; font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
  text-transform: uppercase; margin-bottom: 4px; font-weight: 600;
}
.notice-info { background: var(--honey-dim); border-color: rgba(233, 166, 72, 0.28); color: var(--ink-2); }
.notice-info b { color: var(--honey); }
.notice-error { background: var(--rose-dim); border-color: rgba(232, 115, 95, 0.32); color: #F2B3A4; }
.notice-ok { background: var(--mint-dim); border-color: rgba(89, 201, 165, 0.3); color: var(--mint); }
.import-warnings { margin: 8px 0 0; padding-left: 18px; }
.import-warnings li { margin-top: 3px; }

.pill {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-size: 11.5px; font-weight: 600; padding: 5px 11px; border-radius: 999px;
}
.pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
/* An icon-only pill (the "aggiunto localmente" marker) is a circle, not a stretched capsule
   around one glyph. */
.pill-icon { padding: 6px; width: 26px; height: 26px; justify-content: center; }
.pill-icon .ico { width: 13px; height: 13px; }
.pill-ok { background: var(--mint-dim); color: var(--mint); }
.pill-warn { background: var(--honey-dim); color: var(--honey); }
.pill-off { background: var(--wash); color: var(--muted); }

/* A row of toggle-style filter links (e.g. the portfolio's status filter) — never actually
   styled before now, which read as a run-on sentence of unspaced text. */
.filters { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex; align-items: center; white-space: nowrap;
  font-size: 13px; font-weight: 500; padding: 7px 13px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--muted); background: var(--surf);
}
.chip:hover { color: var(--ink); border-color: var(--line-2); text-decoration: none; }
.chip.on { background: var(--honey); border-color: var(--honey); color: var(--honey-ink); font-weight: 600; }
button.chip { cursor: pointer; font-family: inherit; }
.chip-error { border-color: var(--rose); color: var(--rose); }

/* Import review (Excel preview/correction before commit) — an expandable row's correction
   form sits inside the table itself, so it borrows .doctor-form's grid rather than a dialog. */
.import-row-editor { max-width: none; padding-top: 10px; }
.import-row-readonly-note { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; }

/* ---------- auth pages ---------- */
.auth-wrap { min-height: 68vh; display: grid; place-items: center; padding: 24px 0; }
.auth-box { width: 100%; max-width: 350px; display: grid; gap: 14px; }
.auth-box .logo { font-size: 27px; text-align: center; }
.auth-box .sub { text-align: center; font-size: 13.5px; color: var(--muted); margin-bottom: 4px; }
.auth-alt { text-align: center; font-size: 12.5px; color: var(--muted); }

/* ---------- tables ---------- */
.table-scroll { overflow-x: auto; }
table.data { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 720px; }
table.data th {
  text-align: left; font-family: var(--mono); font-weight: 400; font-size: 10px;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted);
  padding: 0 12px 10px 0;
}
table.data td { padding: 11px 12px 11px 0; border-top: 1px solid var(--line); color: var(--ink-2); }
table.data td.name { color: var(--ink); font-weight: 600; }
table.data td.actions { text-align: right; white-space: nowrap; }
table.data td.actions .btn { margin-left: 6px; }
/* .confirm-inline is a <div>, block by default — white-space: nowrap above only keeps text and
   inline content on one line, so it forced a line break of its own regardless, dropping the
   delete icon onto its own row under Sospendi/Rimuovi admin instead of sitting beside them. */
table.data td.actions .confirm-inline { display: inline-block; vertical-align: middle; margin-left: 6px; }

.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 24px; }
@media (max-width: 700px) { .stats { grid-template-columns: repeat(2, 1fr); } }
.stat { background: var(--surf); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 14px 16px; }
.stat b { display: block; font-size: 25px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); }
.stat span { font-size: 11.5px; color: var(--muted); }

.tnum { font-variant-numeric: tabular-nums; }

/* ---------- the day (Dashboard) ---------- */
/* Warnings that need doing something: a row each, the whole row a link to where it is done. */
.dash-alerts { display: grid; gap: 8px; margin-bottom: 18px; }
.dash-alert {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-radius: var(--r-md);
  background: var(--rose-dim); color: var(--ink); text-decoration: none; font-size: 14px; font-weight: 600;
  border: 1px solid transparent;
}
.dash-alert:hover { border-color: var(--rose); text-decoration: none; }
.dash-alert-icon { color: var(--rose); font-size: 16px; }
.dash-alert-go { margin-left: auto; color: var(--muted); font-size: 18px; }
/* A number that leads somewhere is a link, and looks it on hover. */
a.stat-link { text-decoration: none; color: inherit; }
a.stat-link:hover { border-color: var(--honey); text-decoration: none; }
.stat b small { font-size: 15px; font-weight: 500; color: var(--muted); }

.dash-day { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 14px; align-items: start; }
.dash-side { display: grid; gap: 14px; }
@media (max-width: 900px) { .dash-day { grid-template-columns: minmax(0, 1fr); } }

/* Today, hour by hour: each visit the calendar's own appointment — category stripe on the left —
   laid out with room for what is needed at the door. */
.agenda { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.agenda-item {
  display: grid; grid-template-columns: 58px minmax(0, 1fr); gap: 12px;
  padding: 12px 14px 12px 12px; border-radius: var(--r-md);
  background: var(--doctor-bg); border: 1px solid var(--doctor-line); border-left: 6px solid var(--doctor-line);
}
.agenda-item.is-done { opacity: 0.62; }
/* On a phone the hour goes above the name instead of beside it: the column it took was the room
   the three buttons needed to stay on one line. */
@media (max-width: 520px) {
  .agenda-item { grid-template-columns: minmax(0, 1fr); gap: 4px; padding: 10px 12px 12px 10px; }
  .agenda-item .agenda-time { display: flex; align-items: baseline; gap: 6px; }
  .agenda-item .agenda-time span::before { content: "– "; }
}
.agenda-time { display: grid; align-content: start; gap: 2px; font-family: var(--mono); }
.agenda-time b { font-size: 15px; color: var(--ink); }
.agenda-time span { font-size: 11.5px; color: var(--muted); }
.agenda-body { display: grid; gap: 5px; min-width: 0; }
.agenda-who { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.agenda-who a { font-weight: 600; font-size: 15px; color: var(--ink); }
.agenda-who .visit-status { padding: 3px 9px; background-image: none; cursor: default; font-size: 11.5px; }
.agenda-where { font-size: 13px; color: var(--muted); }
.agenda-warn { font-size: 13px; font-weight: 700; color: var(--rose); }
.agenda-inside { font-size: 13px; color: var(--ink-2); }
.agenda-inside .dialog-label { display: block; margin-bottom: 2px; }
.agenda-note { font-size: 13px; font-style: italic; color: var(--ink-2); white-space: pre-wrap; }
.agenda-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 4px; }
.agenda-actions form { margin: 0; }
.agenda-actions .phone-menu { flex: 0 0 auto; }
/* One height for the row's three buttons — directions, the phone menu, "fatta" — which come from
   three components each with its own idea of a button's size. */
.agenda-actions .btn, .agenda-actions .phone-menu > summary {
  height: 38px; min-height: 0; padding: 0 14px; font-size: 13px;
  display: inline-flex; align-items: center; gap: 6px;
}

/* The days coming: one line each, date, how many, who. */
.next-days { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.next-days a {
  display: grid; grid-template-columns: 92px 70px minmax(0, 1fr); align-items: baseline; gap: 8px;
  padding: 8px 10px; border-radius: var(--r-sm); background: var(--wash-soft); border: 1px solid var(--line);
  color: var(--ink); text-decoration: none; font-size: 13px;
}
.next-days a:hover { border-color: var(--honey); text-decoration: none; }
.next-day-date { font-weight: 600; }
.next-day-count { color: var(--muted); }
.next-day-who { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- the month's summary (Riepilogo) ----------
   One series everywhere, so one colour: the app's own honey for every bar, meter and column, on a
   quiet track. The numbers are written in ink beside the marks, never in the bar's colour. Bars
   end in a 4px round and start flat on their baseline. */
.dash-stats { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.dash-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: start; }
.dash-wide { grid-column: 1 / -1; }
@media (max-width: 860px) { .dash-grid { grid-template-columns: minmax(0, 1fr); } }
.dash-foot { margin-top: 14px; }
.dash-more { margin-top: 12px; }

.dash-meters { display: grid; gap: 14px; }
.dash-meter-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; font-size: 13px; color: var(--ink-2); }
.dash-meter-head b { color: var(--ink); }
.dash-track { height: 10px; border-radius: 4px; background: var(--wash); overflow: hidden; }
.dash-fill { height: 100%; background: var(--honey); border-radius: 0 4px 4px 0; }

.dash-bars { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.dash-bars li { display: grid; grid-template-columns: minmax(0, 110px) minmax(0, 1fr) 36px; align-items: center; gap: 10px; font-size: 13px; }
.dash-bar-label { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-bar-track { height: 12px; background: var(--wash); border-radius: 4px; overflow: hidden; }
.dash-bar-fill { display: block; height: 100%; background: var(--honey); border-radius: 0 4px 4px 0; }
.dash-bar-value { color: var(--ink); text-align: right; font-weight: 600; }

.dash-columns { display: flex; align-items: flex-end; gap: 10px; height: 170px; }
.dash-column { flex: 1 1 0; min-width: 0; height: 100%; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.dash-column-value { font-size: 13px; font-weight: 600; color: var(--ink); }
.dash-column-track { flex: 1; width: min(56px, 100%); display: flex; align-items: flex-end; background: var(--wash); border-radius: 4px 4px 0 0; }
.dash-column-fill { width: 100%; background: var(--honey); border-radius: 4px 4px 0 0; }
/* The folded tail is context, not a category: drawn in the track's grey so a large "Altri" does not
   read as the leader. */
.dash-bars li.is-other .dash-bar-fill { background: var(--faint); }
.dash-bars li.is-other .dash-bar-label { color: var(--muted); }
.dash-column-label { font-size: 11.5px; color: var(--muted); white-space: nowrap; }

/* Sized globally: an inline SVG with no intrinsic dimensions falls back to 300x150, so an icon
   used anywhere this rule does not reach renders enormous. */
.ico { width: 16px; height: 16px; flex-shrink: 0; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* Blazor's own error bar, restyled so it does not appear as unstyled white. */
#blazor-error-ui {
  background: var(--rose); color: #2A0F09; bottom: 0; display: none;
  left: 0; padding: 12px 16px; position: fixed; width: 100%; z-index: 1000;
  font-size: 14px; font-weight: 600;
}
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 14px; top: 10px; }

/* ============================================================================
   Search, results and cards
   ========================================================================== */
.search-bar { display: grid; gap: 10px; margin-bottom: 24px; }
.search-input { font-size: 16px; }              /* 16px stops iOS zooming on focus */

.search-row { display: flex; gap: 8px; align-items: center; }
.search-row .search-input { flex: 1; min-width: 0; }
/* A square icon button next to the search field, not a full-width row of its own — the filter
   count sits as a small pill over its corner rather than pushing the icon off to one side. */
.btn-icon { flex: 0 0 auto; width: 44px; padding: 0; position: relative; }
.btn-icon .phone-count {
  position: absolute; top: -4px; right: -4px;
  background: var(--rose); color: #fff; min-width: 16px; height: 16px;
  font-size: 9.5px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center;
}
/* Same idea as .btn-icon, but sized to sit next to a row of .btn-sm text buttons rather than
   next to a full-height search field. */
.btn-icon-sm { flex: 0 0 auto; width: 34px; height: 34px; min-height: 0; padding: 0; line-height: 1; }
/* The planner's row of controls is one size throughout — the view switch, the arrows, edit and
   export all 34 × 34, as the rep asked: the arrows and the export menu used to be 44 and stood
   out beside the edit button. The chevrons stay real SVG rather than ‹ / › characters, which
   rendered thin at this size; the icons share one size so none looks heavier than the rest. */
.planner-nav .btn-icon-sm .ico { width: 17px; height: 17px; }
/* The export menu's summary is styled as a generic 44-pixel menu trigger elsewhere (the portfolio
   uses it beside a full-height search field); here it has to match the buttons it sits among. */
.planner-nav .action-menu > summary {
  width: 34px; height: 34px;
  border-radius: var(--r-sm); background: var(--wash-soft); color: var(--ink);
}

.result-count {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 14px;
}

.results-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}

/* ---------- card ---------- */
.doctor-card {
  position: relative; display: flex; flex-direction: column; gap: 14px;
  padding: 18px; transition: border-color 0.15s, transform 0.15s;
}
.doctor-card:hover { border-color: var(--line-2); }

/* One overlay link makes the whole card open the profile without nesting interactive elements
   inside an anchor, which is invalid and unreadable to a screen reader. The call and directions
   buttons paint above it. */
.doctor-card-open { position: absolute; inset: 0; z-index: 1; border-radius: var(--r-xl); }
.doctor-card:focus-within { border-color: var(--honey); }

.doctor-card-head { display: flex; gap: 12px; align-items: center; }
.avatar {
  width: 42px; height: 42px; border-radius: 13px; flex-shrink: 0;
  background: var(--surf-3); color: #6E7885; display: grid; place-items: center; overflow: hidden;
}
.doctor-card-identity { min-width: 0; flex: 1; }
.doctor-card-identity h2 {
  font-size: 17.5px; font-weight: 600; line-height: 1.25; letter-spacing: -0.02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.doctor-card-identity p { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.doctor-card-identity .prov { opacity: 0.7; }

.type-badge {
  flex-shrink: 0; align-self: flex-start;
  font-family: var(--mono); font-size: 10px; font-weight: 500; letter-spacing: 0.1em;
  padding: 4px 8px; border-radius: 6px; border: 1px solid;
}
.type-badge.mmg { color: var(--honey); border-color: rgba(233, 166, 72, 0.32); background: var(--honey-dim); }
.type-badge.pls { color: var(--mint); border-color: rgba(89, 201, 165, 0.32); background: var(--mint-dim); }
/* No industry-standard palette exists for these specialty codes — they are the rep's own
   shorthand, not a medical classification system — so each gets its own hand-picked color.
   An unrecognised code falls back to .specialist (neutral grey). */
.type-badge.aic { color: var(--pink); border-color: rgba(224, 111, 176, 0.32); background: var(--pink-dim); }
.type-badge.car { color: var(--coral); border-color: rgba(232, 96, 138, 0.32); background: var(--coral-dim); }
.type-badge.dia { color: var(--violet); border-color: rgba(167, 139, 250, 0.32); background: var(--violet-dim); }
.type-badge.enc { color: var(--sky); border-color: rgba(111, 168, 220, 0.32); background: var(--sky-dim); }
.type-badge.ger { color: var(--tan); border-color: rgba(192, 138, 91, 0.32); background: var(--tan-dim); }
.type-badge.int { color: var(--slate); border-color: rgba(143, 166, 194, 0.32); background: var(--slate-dim); }
.type-badge.ipr { color: var(--magenta); border-color: rgba(200, 95, 192, 0.32); background: var(--magenta-dim); }
.type-badge.lip { color: var(--olive); border-color: rgba(179, 194, 76, 0.32); background: var(--olive-dim); }
.type-badge.meu { color: var(--teal); border-color: rgba(63, 191, 168, 0.32); background: var(--teal-dim); }
.type-badge.nef { color: var(--cyan); border-color: rgba(79, 198, 217, 0.32); background: var(--cyan-dim); }
.type-badge.pne { color: var(--indigo); border-color: rgba(140, 122, 224, 0.32); background: var(--indigo-dim); }
/* Not one more specialty among the others: a place rather than a person, so it gets the one
   colour in this palette that is not a doctor's. */
.type-badge.str { color: var(--steel); border-color: rgba(143, 179, 201, 0.32); background: var(--steel-dim); }
.type-badge.specialist { color: var(--faint); border-color: var(--line-2); background: var(--wash); }

/* Clamped to one line: a two-line address here, next to a one-line one on the card beside it,
   is the single biggest reason the sections below (hours, registry, actions) landed at a
   different height card to card. The full address is always one tap away on the profile page. */
.doctor-card-address {
  font-size: 13.5px; color: var(--ink-2); display: flex; gap: 8px; align-items: center;
  height: 20px; line-height: 20px;
}
.doctor-card-address .pin { width: 15px; height: 15px; flex-shrink: 0; color: var(--muted); }
.doctor-card-address span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* The brick under the address, lined up with its text rather than with the pin. */
.doctor-card-brick {
  display: flex; align-items: center; gap: 7px; margin-top: 2px; padding-left: 23px;
  font-size: 12px; color: var(--ink-2);
}
.doctor-card-brick-label {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted);
}

/* ---------- week strip ---------- */
.week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.week-day { display: grid; gap: 5px; justify-items: center; }
.week-bar { display: block; width: 100%; height: 4px; border-radius: 2px; background: var(--wash-3); }
.week-day.open .week-bar { background: var(--honey); box-shadow: 0 0 9px -2px var(--honey); }
.week-label { font-family: var(--mono); font-size: 9.5px; color: var(--faint); line-height: 1; }
.week-day.open .week-label { color: var(--muted); }

/* One field per row on a fixed two-column grid, rather than flex-wrap: a shorter pair like
   "Massimale / ASL" used to fit on one line while a longer one forced its own, so the value
   column landed in a different place from card to card and even row to row on the same card. */
.doctor-card-registry {
  display: grid; grid-template-columns: max-content 1fr; column-gap: 10px; row-gap: 5px;
  margin: 0; padding: 8px 10px; background: var(--wash-soft); border-radius: var(--r-sm);
  font-size: 11.5px;
  /* Reserved for the full 6 fields (massimale, ASL, distretto, codice fiscale, data di
     nascita, email) regardless of how many this particular doctor actually has, so notes and
     actions below it start at the same height on every card, not just ones with every field. */
  min-height: 131px;
}
.doctor-card-registry div { display: contents; }
.doctor-card-registry dt { color: var(--muted); white-space: nowrap; line-height: 15px; }
.doctor-card-registry dd { margin: 0; color: var(--ink-2); font-weight: 500; line-height: 15px; }

.doctor-card-nohours, .doctor-card-note, .clinic-note { font-size: 12.5px; color: var(--muted); }
/* Matches the WeekStrip + hours-lines + more-line height of a card that does have hours, so a
   doctor with no published schedule doesn't leave everything below it sitting higher than on
   the cards around it. */
.doctor-card-nohours { display: flex; align-items: center; min-height: 94px; margin: 0; }
.clinic-note {
  border-left: 2px solid var(--line); padding-left: 10px; line-height: 1.5; font-size: 13px;
}
.doctor-card-note {
  border-left: 2px solid var(--line); padding-left: 10px; line-height: 1.45;
  /* Notes run past 200 characters upstream; unclamped they are the tallest thing on the card. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.doctor-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: auto; position: relative; z-index: 2; }
/* While "Aggiungere?" is showing, Chiama/Indicazioni are just noise crowding a small confirm —
   hide everything except the form asking the question. */
.doctor-card-actions:has(.confirm-inline-yesno:not([hidden])) {
  justify-content: center;
}
.doctor-card-actions:has(.confirm-inline-yesno:not([hidden])) > :not(.card-add) { display: none; }
.doctor-card-actions .btn { flex: 1; min-width: 0; padding: 11px 12px; font-size: 13.5px; }
/* Nothing left to act on (the drawer's cards: no telephone, no directions, already on the round):
   the row would otherwise leave a gap under the card as if something had failed to load. */
.doctor-card-actions:empty { display: none; }
/* The notes written out on the card, where they are read to choose between two doctors rather
   than opened one at a time. Each one clamped: a card is a glance, the profile has them whole. */
/* Every history (HistoryPager.razor, paged by menus.js): a window as tall as the two entries on
   show — sized by the script, since entries are not all one height — and the list moved under it.
   Without the script the window has no height set and the whole list shows. */
.history-window { overflow: hidden; position: relative; transition: height 0.2s ease; }
[data-notes-list] { transition: transform 0.2s ease; }
.doctor-card .history-pager { margin-top: 10px; }
/* A list that scrolled on its own before (the notes dialog on "Cerca") is paged now, not scrolled. */
.history-window .note-list { max-height: none; overflow: visible; }
.doctor-card-notes { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.doctor-card-notes li {
  background: var(--wash-soft); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 7px 9px;
}
.doctor-card-notes time {
  display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.07em;
  color: var(--muted); margin-bottom: 3px;
}
.doctor-card-notes p {
  font-size: 12.5px; color: var(--ink-2); white-space: pre-wrap;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
/* Full width, flanking the list above and below rather than beside it — the card is already
   narrow, and a button on each side would leave less room for the note than the note needs. */
.notes-nav {
  display: flex; align-items: center; justify-content: center; width: 100%; height: 16px;
  margin: 2px 0; padding: 0; border: 0; border-radius: 6px; cursor: pointer;
  background: var(--wash-soft); color: var(--muted); position: relative; z-index: 2;
}
.notes-nav svg { width: 13px; height: 13px; }
.notes-nav:hover { background: var(--wash); color: var(--ink); }
.notes-nav[hidden] { display: none; }
.doctor-card-actions .btn-primary { flex: 1.4; }
.doctor-card-actions .ico { width: 14px; height: 14px; flex-shrink: 0; }
.doctor-card-extra-phones { display: flex; gap: 7px; flex-wrap: wrap; position: relative; z-index: 2; }

.pager { display: flex; gap: 6px; align-items: center; justify-content: center; margin-top: 30px; flex-wrap: wrap; }
.pager-gap { color: var(--muted); padding: 0 4px; }

/* Skeletons hold the layout while a query runs, so results do not jump into place. */
.skeleton { min-height: 214px; opacity: 0.5; }
.skeleton::after {
  content: ""; display: block; height: 100%;
  background: linear-gradient(100deg, transparent 20%, var(--wash) 45%, transparent 70%);
  background-size: 220% 100%;
  animation: skeleton-sweep 1.3s ease-in-out infinite;
}
@keyframes skeleton-sweep {
  from { background-position: 140% 0; }
  to { background-position: -40% 0; }
}
@media (prefers-reduced-motion: reduce) { .skeleton::after { animation: none; } }

/* ---------- doctor profile ---------- */
.back-link { margin-bottom: 18px; font-size: 14px; }
.back-link a { color: var(--muted); }
.back-link a:hover { color: var(--ink); text-decoration: none; }

.detail-head { display: flex; gap: 18px; align-items: flex-start; margin-bottom: 26px; flex-wrap: wrap; }
.avatar-lg { width: 78px; height: 78px; border-radius: 22px; }
.detail-head h1 { font-size: clamp(24px, 4vw, 31px); }
.detail-role { color: var(--muted); font-size: 14.5px; margin-top: 4px; }
.detail-badges { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 12px; }

/* One column of cards, stacked in reading order (see DoctorDetail): the surgery, logging a visit,
   the details, the round, the personal notes. minmax(0, 1fr) rather than 1fr so a long unbroken
   line (an email, a codice fiscale) cannot widen the column past the page. */
.detail-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; }
.detail-main { display: grid; gap: 14px; }
.detail-side { display: grid; gap: 14px; align-content: start; }

.clinic { display: grid; gap: 14px; }
.clinic-head { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; }
.clinic-head h2 { font-size: 16.5px; font-weight: 600; }
.clinic-head p { font-size: 13px; color: var(--muted); margin-top: 3px; }
.clinic-head-side { display: flex; gap: 8px; align-items: center; flex: 0 0 auto; }
.clinic-head-side .btn-icon-sm .ico { width: 15px; height: 15px; }
.clinic-struttura { font-size: 12.5px; color: var(--honey); font-weight: 600; margin-top: 2px; }
/* A bare address and a bare facility name read the same at a glance; a small label above each
   says which is which without competing with the value for attention. */
.clinic-field-label {
  display: block; font-size: 10px; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--faint); margin-top: 8px;
}
.clinic-field-label:first-child { margin-top: 0; }
/* The comune line reads fine on one line with its label, unlike the address/struttura above it
   which each carry enough text to want their own line. */
.clinic-field-label.inline { display: inline; margin-top: 0; margin-right: 5px; }
.clinic-actions { display: flex; gap: 9px; flex-wrap: wrap; }
/* Calling is the primary action, so it takes the larger share rather than whatever is left
   over after the secondary button has sized itself to its own text. */
.clinic-actions > * { flex: 1.5 1 0; min-width: 0; }
.clinic-actions > .btn { flex: 1 1 0; }

table.schedule { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.schedule td { padding: 8px 0; border-top: 1px solid var(--line); color: var(--ink-2); vertical-align: top; }
table.schedule td.day { color: var(--muted); width: 104px; }
table.schedule tr.closed td { color: var(--faint); }
.interval-note { color: var(--muted); font-size: 12.5px; }
.interval-note::before { content: " · "; }
@media (max-width: 480px) {
  /* At this width the note wrapped mid-phrase against the time; give it its own line. */
  .interval-note { display: block; }
  .interval-note::before { content: none; }
}

.side-title { font-size: 14px; font-weight: 600; margin-bottom: 12px; }
dl.kv { display: grid; gap: 9px; margin: 0; }
dl.kv > div { display: flex; justify-content: space-between; gap: 12px; font-size: 13.5px; }
dl.kv dt { color: var(--muted); }
dl.kv dd { margin: 0; color: var(--ink-2); text-align: right; }

/* ---------- opening hours on the card ---------- */
.doctor-card-hours { display: grid; gap: 10px; }

/* Fixed at exactly 3 rows' worth of height — the card caps how many grouped lines it renders
   to match (see DoctorCard's MaxHourLines) — so a doctor with a simple weekday schedule and one
   with a complicated split-shift one take up the same space instead of pushing the registry box
   and actions below to two different heights. */
dl.hours-lines { display: grid; gap: 3px; margin: 0; font-size: 12.5px; height: 51px; overflow: hidden; }
/* Except where the card shows every line (see DoctorCard's AllHours): there the fixed height was
   cutting off exactly the day being looked for, three lines in, with nothing to say it had. */
dl.hours-lines-all { height: auto; overflow: visible; }
dl.hours-lines > div { display: flex; gap: 10px; align-items: baseline; line-height: 15px; }
dl.hours-lines dt {
  color: var(--muted); flex-shrink: 0; min-width: 58px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.04em;
}
dl.hours-lines dd { margin: 0; color: var(--ink-2); }

.doctor-card-hours-more { margin: 0; height: 14px; line-height: 14px; font-size: 11px; color: var(--muted); }

/* ---------- phone menu ---------- */
.phone-menu { position: relative; flex: 1.4; min-width: 0; }

.phone-menu > summary {
  width: 100%; cursor: pointer; list-style: none;
  /* The default disclosure triangle would sit beside a chevron that already says the same
     thing, and it cannot be styled consistently across browsers. */
}
.phone-menu > summary::-webkit-details-marker { display: none; }
.phone-menu > summary::marker { content: ""; }
.phone-menu > summary .phone-count {
  font-family: var(--mono); font-size: 10.5px; font-weight: 600;
  padding: 1px 6px; border-radius: 999px;
  background: rgba(36, 24, 4, 0.18); color: inherit;
}
.phone-menu > summary .chevron { width: 14px; height: 14px; transition: transform 0.15s; }
.phone-menu[open] > summary .chevron { transform: rotate(180deg); }

.phone-menu-list {
  position: absolute; z-index: 5; top: calc(100% + 6px); left: 0; min-width: 100%;
  display: grid; gap: 6px; padding: 8px;
  background: var(--surf-2); border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-pop-sm);
}
.phone-menu-list .btn { justify-content: flex-start; white-space: nowrap; }

/* ---------- action menu (e.g. Esporta/Importa Excel, tucked behind one icon button) ---------- */
.action-menu { position: relative; flex: 0 0 auto; }
.action-menu > summary {
  width: 44px; height: 44px; display: grid; place-items: center;
  cursor: pointer; list-style: none;
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surf); color: var(--ink-2);
}
.action-menu > summary::-webkit-details-marker { display: none; }
.action-menu > summary::marker { content: ""; }
.action-menu-list {
  position: absolute; z-index: 5; top: calc(100% + 6px); right: 0; min-width: 170px;
  display: grid; gap: 6px; padding: 8px;
  background: var(--surf-2); border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-pop-sm);
}
.action-menu-list .btn { justify-content: flex-start; white-space: nowrap; }

/* ---------- settings ---------- */
.settings-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
.settings-hint { font-size: 13px; color: var(--muted); margin-bottom: 14px; }
.settings-options { display: grid; gap: 8px; }
.settings-option {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; text-align: left; cursor: pointer;
  font-family: var(--sans); font-size: 14.5px; font-weight: 500;
  padding: 13px 15px; min-height: 48px;
  border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--wash-soft); color: var(--ink);
  transition: border-color 0.15s, background 0.15s;
}
.settings-option:hover { background: var(--wash-2); text-decoration: none; }
.settings-option.on { border-color: var(--honey); background: var(--honey-dim); }
.settings-option-check { color: var(--honey); font-weight: 700; }

/* The account name in the bar is now the way into settings, so it has to look reachable. */
a.me { color: var(--ink-2); }
a.me:hover { color: var(--ink); text-decoration: none; }

/* ---------- static-render form controls ---------- */

/* Unconditionally hidden — see Search.razor's own remark on why there is no <noscript>
   fallback to unhide it. Pressing Enter in the search field still submits the form via this
   button with no JavaScript involved, so nothing is actually lost by hiding it outright. */
.chip-submit { display: none; }

/* ---------- language flags ---------- */
.flag {
  width: 15px; height: 10px; flex-shrink: 0; border-radius: 1.5px;
  /* A hairline keeps the white band of the tricolour from bleeding into a light surface. */
  box-shadow: 0 0 0 1px var(--ring);
}
.lang a, .menu-lang a { display: inline-flex; align-items: center; gap: 6px; }
.settings-option-label { display: inline-flex; align-items: center; gap: 9px; }

/* Arrow and label share a centre line; a text arrow glyph never quite does. */
.back-link a { display: inline-flex; align-items: center; gap: 7px; }
.back-link svg { width: 16px; height: 16px; flex-shrink: 0; }

/* ---------- personal layer ---------- */
.avatar-photo { object-fit: cover; display: block; }

.personal .settings-hint { margin-bottom: 12px; }
.personal-photo { margin-bottom: 8px; }
.personal-photo label { cursor: pointer; }
.btn-block { width: 100%; }

.personal-note-form { display: grid; gap: 8px; }
.personal-note-form textarea { resize: vertical; min-height: 68px; font-size: 14px; }

.note-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 10px; }
.note-list li {
  background: var(--wash-soft); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 10px 12px;
}
.note-list time {
  display: block; font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  color: var(--muted); margin-bottom: 4px;
}
.note-list p { font-size: 13.5px; color: var(--ink-2); white-space: pre-wrap; }
/* A secondary action written as words ("Non è una visita"): quiet until pointed at. */
.link-action {
  margin-top: 7px; background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--sans); font-size: 12px; color: var(--muted);
}
.link-action:hover { color: var(--rose); }
/* A personal note is deleted with the same bin, in the same corner, as a visit. */
.note-list li { position: relative; padding-right: 46px; }

.type-badge.local {
  color: var(--mint); border-color: rgba(89, 201, 165, 0.32); background: var(--mint-dim);
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0;
}
.type-badge.local .ico { width: 13px; height: 13px; }

/* ---------- admin doctor form ---------- */
.doctor-form { display: grid; gap: 14px; max-width: 720px; }
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.doctor-form .field span {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--muted); display: block; margin-bottom: 6px;
}
.doctor-form .field em { font-style: normal; text-transform: none; letter-spacing: 0; }
.doctor-form textarea { resize: vertical; }

.hours-editor { display: grid; gap: 7px; }
.hours-row { display: grid; grid-template-columns: 92px 110px 110px 1fr; gap: 8px; align-items: center; }
.hours-row > span { font-size: 13px; color: var(--muted); }
.hours-row .input { min-height: 40px; padding: 8px 10px; font-size: 13.5px; }
/* The second (afternoon) slot for the same day — grouped tight against its own first row, with
   the day label left blank since it already showed above. */
.hours-row-second { margin-top: -3px; margin-bottom: 4px; }
@media (max-width: 640px) {
  .hours-row { grid-template-columns: 74px 1fr 1fr; }
  .hours-row .input:last-child { grid-column: 1 / -1; }
}

.form-actions { display: flex; gap: 10px; }
.form-actions .btn { flex: 1; }
.inline-form { display: inline; }

/* ---------- note chip and dialog on a card ---------- */
.note-chip {
  position: relative; z-index: 2; align-self: flex-start;
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  font-family: var(--sans); font-size: 12.5px; font-weight: 600;
  padding: 6px 11px; border-radius: 999px;
  border: 1px solid rgba(233, 166, 72, 0.3); background: var(--honey-dim); color: var(--honey);
}
.note-chip:hover { background: rgba(233, 166, 72, 0.2); }
.note-chip .ico { width: 13px; height: 13px; }

.note-dialog {
  width: min(440px, calc(100vw - 32px)); padding: 0; border: 1px solid var(--line-2);
  border-radius: var(--r-lg); background: var(--surf-2); color: var(--ink);
  box-shadow: var(--shadow-pop);
}
.note-dialog::backdrop { background: var(--backdrop); }
.note-dialog header {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 16px 18px 12px; border-bottom: 1px solid var(--line);
}
.note-dialog h2 { font-size: 15px; font-weight: 600; flex: 1; line-height: 1.35; }
/* ---------- one small set of controls, the same everywhere ----------
   ✕ in a grey circle: closes a dialog, or takes something off a list. The calendar's own × on an
   appointment is the model (.fc-event-delete). Closing turns it darker on hover; taking off, which
   changes data, turns it red (.icon-x-danger). A red bin (.visit-delete-btn) deletes a record.
   Anything that changes data asks first, in place (data-confirm-inline) — the calendar's own ×,
   with no room for that inside an appointment, is the one that asks with the browser's dialog. */
.dialog-close, .icon-x {
  display: inline-grid; place-items: center; flex-shrink: 0;
  width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--surf-3); color: var(--muted); font-size: 13px; line-height: 1;
  text-decoration: none;
}
.dialog-close:hover { background: var(--line-2); color: var(--ink); text-decoration: none; }
.icon-x-danger:hover { background: var(--rose); color: #fff; }
/* A section of a dialog — "Nota della visita", "Medici in questa struttura", "Storico": one look,
   the field labels' own, rather than three. */
.dialog-label {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 6px;
}
.note-dialog .note-list { margin: 0; padding: 14px 18px; max-height: 46vh; overflow-y: auto; }
.note-dialog > .btn { margin: 0 18px 18px; width: calc(100% - 36px); }
/* .note-dialog itself is padding: 0 — only .note-list (above) was ever padded for it. A plain
   form (the portfolio filter dialog) needs its own, or its fields sit flush against the edges. */
.note-dialog > form { padding: 16px 18px 18px; }

/* Shares .note-dialog's chrome (border, backdrop, header) rather than repeating it — only the
   width and the content padding actually need to differ, since #planner-search-panel brings its
   own spacing when it lives in the sidebar and needs a little breathing room in here too. */
.planner-add-dialog {
  width: min(360px, calc(100vw - 32px)); padding: 0; border: 1px solid var(--line-2);
  border-radius: var(--r-lg); background: var(--surf-2); color: var(--ink);
  box-shadow: var(--shadow-pop);
}
.planner-add-dialog::backdrop { background: var(--backdrop); }
/* iPhone zooms the whole page when a field under 16px takes focus — the same reason the main
   search box is 16px. Both planner dialogs put a finger (or the add dialog's own autofocus) in a
   15px field, and the page zoomed in behind them; that is one way the rep ended up zoomed with the
   dialog off screen. Touch screens only, so the desktop keeps the app's usual field size. */
@media (pointer: coarse) {
  .planner-add-dialog .input,
  .visit-note-form .input,
  .inbox-search .input { font-size: 16px; }
}

/* "Da abbinare": appointments typed in Google, waiting for their doctor. */
.planner-inbox-notice { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.inbox-list { display: grid; gap: 14px; }
.inbox-item { display: grid; gap: 10px; }
.inbox-item-head h2 { font-size: 17px; font-weight: 600; margin-top: 2px; }
.inbox-when { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--muted); }
.inbox-note { font-size: 13px; color: var(--ink-2); margin-top: 4px; white-space: pre-wrap; }
.inbox-label { font-size: 12px; color: var(--muted); }
.inbox-choices { display: grid; gap: 6px; }
/* A button dressed as the add dialog's candidate row: the same look for the same act. */
.inbox-choice { width: 100%; text-align: left; font: inherit; color: inherit; }
.planner-candidate .inbox-choice-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0; }
.planner-candidate .inbox-choice-head .type-badge { display: inline-block; margin: 0; font-size: 9px; padding: 2px 6px; }
.inbox-search { display: flex; gap: 8px; }
.inbox-search .input { flex: 1; }
.inbox-dismiss { justify-self: start; }
.planner-add-dialog header {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 16px 18px 12px; border-bottom: 1px solid var(--line);
}
.planner-add-dialog h2 { font-size: 15px; font-weight: 600; flex: 1; line-height: 1.35; }
#planner-add-dialog-slot { padding: 14px 18px 18px; max-height: 60vh; overflow-y: auto; }
#planner-add-dialog-slot .side-title { display: none; }

.form-photo {
  display: block; margin-top: 10px; width: 96px; height: 96px;
  object-fit: cover; border-radius: var(--r-md); border: 1px solid var(--line);
}

/* ---------- admin list toolbar ---------- */
.admin-toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 18px; flex-wrap: wrap; }
.admin-search { flex: 1 1 240px; display: flex; gap: 8px; }
.admin-search .input { flex: 1; }
.data .prov { color: var(--muted); }


/* ============================================================================
   Data tables on a phone
   A five-column table cannot be made to fit, and hiding columns only loses
   data. Below the breakpoint each row becomes a stacked card, with the header
   name carried in as a label so nothing needs explaining.
   ========================================================================== */
@media (max-width: 720px) {
  /* table.data sets min-width: 720px, and a type-plus-class selector outranks a plain class —
     so this override has to match that specificity or the table stays wide and the card layout
     is simply scrolled off-screen. */
  table.data-cards { min-width: 0; display: block; }

  /* The horizontal scroller and the panel chrome are both pointless once rows are cards, and
     the panel's border doubled up around every one of them. */
  .table-scroll:has(.data-cards) {
    overflow-x: visible; padding: 0; border: 0; background: none; box-shadow: none;
  }

  .data-cards thead { display: none; }
  .data-cards tbody, .data-cards tr, .data-cards td { display: block; width: 100%; }

  .data-cards tr {
    border: 1px solid var(--line); border-radius: var(--r-lg);
    background: var(--surf); padding: 14px 16px; margin-bottom: 10px;
  }

  .data-cards td { border: 0; padding: 0; }
  .data-cards td + td { margin-top: 8px; }

  /* Label and value on one line, the label in a fixed column so values line up down the card. */
  .data-cards td[data-label] {
    display: flex; gap: 12px; align-items: baseline; font-size: 13.5px;
  }
  .data-cards td[data-label]::before {
    content: attr(data-label);
    flex: 0 0 96px;
    font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--muted); line-height: 1.7;
  }

  .data-cards td.name {
    font-size: 16.5px; font-weight: 600; color: var(--ink);
    padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid var(--line);
  }

  .data-cards td.actions {
    text-align: left; padding-top: 12px; margin-top: 12px;
    border-top: 1px solid var(--line); display: flex; gap: 8px; flex-wrap: wrap;
  }
  .data-cards td.actions .btn { margin: 0; flex: 1 1 auto; }
  /* A compact icon button (delete) shouldn't stretch to match its text-button siblings. */
  .data-cards td.actions .btn-icon-sm { flex: 0 0 auto !important; }

  /* An empty-state row should not be dressed up as a card. */
  .data-cards tr.empty { border: 0; background: none; padding: 10px 0; }
}

/* ---------- Google sign-in ---------- */
.google-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  background: #FFFFFF; border-color: #FFFFFF; color: #1F1F1F; font-weight: 600;
}
.google-btn:hover { background: #F1F1F1; border-color: #F1F1F1; text-decoration: none; }

.auth-divider {
  display: flex; align-items: center; gap: 12px;
  font-size: 11.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.1em;
}
.auth-divider::before, .auth-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}

/* ---------- schedule a visit ---------- */
/* One row: date, outcome, the note taking what is left, the button at the end — the card is the
   page's full width now, and four fields stacked the height of the screen for a two-second action
   was most of what the rep scrolled past to reach the history. Stacks again on a phone. */
.visit-form {
  display: grid; gap: 10px; align-items: end;
  grid-template-columns: 170px 190px minmax(0, 1fr) auto;
}
/* One height for all four, or the labels above them do not line up: a date input is a couple of
   pixels taller than a select in most browsers, and the row is aligned on the bottom edge. */
.visit-form .input, .visit-form .btn { height: 44px; min-height: 0; }
.visit-form .btn { white-space: nowrap; }
@media (max-width: 720px) {
  .visit-form { grid-template-columns: 1fr 1fr; }
  .visit-form .visit-form-note, .visit-form .btn { grid-column: 1 / -1; }
}
.visit-form .field span {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--muted); display: block; margin-bottom: 5px;
}
.visit-form .input { min-height: 42px; }

/* ============================================================================
   The round
   ========================================================================== */
.round-list { display: grid; gap: 8px; }

.round-row {
  background: var(--surf); border: 1px solid var(--line); border-radius: var(--r-lg);
  color: var(--ink);
}
.round-row:hover { border-color: var(--line-2); background: var(--surf-2); }
/* Overdue is the only state that earns colour: everything else is noise on a list you scan. */
.round-row.due { border-color: rgba(232, 115, 95, 0.32); }
.round-row.soon { border-color: rgba(233, 166, 72, 0.28); }

/* A native <details>/<summary> disclosure: no script needed to expand a card in place, and it
   works the same whether the visitor's JS loaded or not. */
.round-row-summary {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; cursor: pointer; list-style: none;
}
.round-row-summary::-webkit-details-marker { display: none; }
.round-row-summary::after {
  content: ""; width: 8px; height: 8px; flex-shrink: 0;
  border-right: 1.5px solid var(--faint); border-bottom: 1.5px solid var(--faint);
  transform: rotate(45deg); transition: transform 0.15s ease; margin-left: 2px;
}
.round-row[open] .round-row-summary::after { transform: rotate(-135deg); }

.round-row .avatar { width: 38px; height: 38px; border-radius: 12px; }
.round-who { flex: 1; min-width: 0; }
.round-who b { display: block; font-size: 15px; font-weight: 600; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.round-who span { font-size: 12px; color: var(--muted); }
.round-cat { margin-left: 6px; padding: 1px 6px; font-size: 9px; vertical-align: 1px; }

.round-when { text-align: right; flex-shrink: 0; }
.round-when b { display: block; font-size: 13px; font-weight: 600; }
.round-when span { font-size: 11px; color: var(--muted); font-family: var(--mono); }
.round-row.due .round-when b { color: var(--rose); }
.round-row.soon .round-when b { color: var(--honey); }

.round-row-body {
  padding: 0 14px 14px 64px; display: grid; gap: 6px; font-size: 13px; color: var(--ink-2);
}
.round-row-body p { margin: 0; }
.round-row-struttura { color: var(--honey); font-weight: 600; }
.round-row-note { color: var(--muted); }
/* Side by side, centered as a pair, and forced to equal width (flex: 1 1 0, not each button's
   own content) — sized independently they drift apart, one reading noticeably wider than the
   other for no reason a viewer can see. */
.round-row-buttons {
  display: flex; justify-content: center; gap: 8px; margin-top: 2px;
}
.round-row-buttons .btn { flex: 1 1 0; max-width: 200px; }
/* The multi-number case renders as <details class="phone-menu">, not a .btn itself — its own
   flex: 1.4 (sized for the doctor card's Chiama/Indicazioni pair) otherwise wins here and grows
   unconstrained, since the rule above never matches this element. */
.round-row-buttons .phone-menu { flex: 1 1 0; max-width: 200px; }

.admin-doctor-list { display: grid; gap: 8px; }
/* No avatar on this list, so the body's indent starts at the text rather than lining up
   under a picture that isn't there. */
.admin-doctor-row .round-row-body { padding-left: 14px; }
.admin-doctor-row .round-row-summary { padding: 12px 14px; }
.admin-doctor-actions { display: flex; align-items: center; gap: 8px; margin-top: 4px; }

.stat b.due { color: var(--rose); }
.stat b.soon { color: var(--honey); }
.stat b.ok { color: var(--mint); }

.type-badge.mine { color: var(--gold); border-color: var(--gold); background: var(--gold-dim); letter-spacing: 0; }
/* Same slot as .mine, shown instead of it for a doctor not yet in the round — an outline star
   rather than a filled one, same idea as a favorite toggle. */
.type-badge.mine-add { color: var(--faint); border-color: var(--line-2); background: transparent; letter-spacing: 0; }

.card-add { display: flex; }
.card-add .btn { padding: 11px 13px; }

.cadence-form { display: grid; gap: 10px; }
.cadence-form .field span, .visit-form .field span {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--muted); display: block; margin-bottom: 5px;
}

.visit-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 9px; }
.visit-list li {
  background: var(--wash-soft); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 10px 12px;
}
/* One visit in the doctor's history: date and status on top, the delete icon in the corner. */
.visit-list .visit-item { position: relative; }
/* A call made on this doctor inside a place: the same card as the doctor's own visits (see
   DoctorDetail), with its status pill static rather than a menu and one pill more — the place's
   name, in the colours a place has everywhere else, and a link to it. */
.visit-item-inside .visit-status { padding: 5px 11px; background-image: none; cursor: default; }
.visit-place-pill {
  display: inline-flex; align-items: center; max-width: 100%;
  font-size: 12px; font-weight: 600; line-height: 1.2; padding: 5px 11px; border-radius: 999px;
  background: var(--steel-dim); color: var(--steel); text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.visit-place-pill:hover { background: var(--steel); color: #fff; text-decoration: none; }
.visit-item-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding-right: 34px; min-height: 28px; }
/* The date on one line: in the narrow side column it was breaking into three. */
.visit-item-head time { white-space: nowrap; margin-right: 0; }
.visit-status-form { margin: 0; }
/* The status select dressed as the pill it replaces — same colours, same size. */
.visit-status {
  appearance: none; -webkit-appearance: none; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 600; line-height: 1.2;
  padding: 5px 24px 5px 11px; border-radius: 999px; border: 1px solid transparent;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 13px) 55%, calc(100% - 9px) 55%;
  background-size: 4px 4px; background-repeat: no-repeat;
}
.visit-status.pill-ok { background-color: var(--mint-dim); color: var(--mint); }
.visit-status.pill-warn { background-color: var(--honey-dim); color: var(--honey); }
.visit-status.pill-off { background-color: var(--wash); color: var(--muted); }
.visit-delete, .corner-action { position: absolute; top: 8px; right: 8px; z-index: 2; }
.corner-action .confirm-inline-yesno { background: var(--surf); padding: 2px 0 2px 8px; border-radius: 8px; }
.corner-action .confirm-inline-yesno span { white-space: normal; max-width: 260px; line-height: 1.3; }
.visit-delete-btn {
  display: grid; place-items: center; width: 28px; height: 28px; padding: 0; cursor: pointer;
  border-radius: 8px; border: 1px solid transparent; background: var(--rose-dim); color: var(--rose);
}
.visit-delete-btn:hover { background: var(--rose); color: #fff; }
.visit-delete-btn .ico { width: 15px; height: 15px; }
/* The "Eliminare? Sì / No" question opens over the head row, on the card's own background. */
.visit-delete .confirm-inline-yesno { background: var(--surf); padding: 2px 0 2px 8px; border-radius: 8px; }
/* The question now says what else goes with the visit (the calendar, Google), which is longer than
   "Eliminare?": it wraps within a sensible width instead of running off a phone's screen. */
.visit-delete .confirm-inline-yesno span { white-space: normal; max-width: 260px; line-height: 1.3; }

.visit-list time {
  display: inline-block; font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  color: var(--muted); margin-right: 8px;
}
.visit-list p { font-size: 13px; color: var(--ink-2); margin-top: 6px; white-space: pre-wrap; }
/* "Aggiungi nota" / "Modifica nota" on a visit in the history: the same quiet text-link look as
   the delete beside it, opening into the form. */
.visit-note-edit { margin-top: 7px; }
.visit-note-edit > summary {
  list-style: none; cursor: pointer; font-size: 12px; color: var(--muted); width: fit-content;
}
.visit-note-edit > summary::-webkit-details-marker { display: none; }
.visit-note-edit > summary:hover,
.visit-note-edit[open] > summary { color: var(--ink); }
.visit-note-form { display: grid; gap: 8px; margin-top: 8px; }
.visit-note-form .btn { justify-self: start; }

/* ============================================================================
   Weekly planner
   ========================================================================== */
/* Overrides .page-head's larger, more spaced-out defaults: the calendar's own header competes
   with the grid for vertical room right below it, on every view, so it earns a tighter treatment
   the way a one-off page title doesn't. */
.planner-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.planner-head h1 { font-size: clamp(18px, 2.6vw, 22px); }
.planner-head p { margin-top: 2px; font-size: 12.5px; }
.planner-nav { display: flex; align-items: center; gap: 6px; }
.planner-view-switch { display: flex; gap: 2px; margin-right: 4px; }
.planner-view-switch .btn { padding-inline: 10px; }
/* A phone has about 360px for this row, and it needs about 390: the export button went off the
   screen and dragged the whole page sideways with it. Two rows instead — the choice of view across
   the full width, three equal parts; under it the arrows on the left, edit and export on the right.
   The title's row is given the full width too, since the controls no longer sit beside it. */
@media (max-width: 560px) {
  .planner-head > div { flex: 1 1 100%; }
  .planner-nav { flex-wrap: wrap; row-gap: 8px; }
  .planner-view-switch { flex: 1 1 100%; margin-right: 0; }
  .planner-view-switch .btn { flex: 1 1 0; min-width: 0; padding-inline: 6px; }
  .planner-nav-arrow + .planner-nav-arrow { margin-right: auto; }
}

.planner-main { min-width: 0; }

.planner-search-form { margin-bottom: 10px; display: flex; gap: 8px; }
.planner-search-form .input { flex: 1 1 auto; }

.planner-candidates { display: flex; flex-direction: column; gap: 6px; }
.planner-candidate {
  background: var(--surf-2); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 8px 10px; cursor: pointer;
}
.planner-candidate:hover { border-color: var(--honey); }
.planner-candidate strong { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink); }
.planner-candidate span { display: block; font-size: 11px; color: var(--muted); margin-top: 1px; }

/* FullCalendar re-themed to the app's own tokens via its documented CSS custom properties,
   rather than overriding its classes directly — this survives a library upgrade cleanly. */
#planner-calendar {
  --fc-page-bg-color: transparent;
  --fc-neutral-bg-color: var(--surf);
  --fc-neutral-text-color: var(--ink-2);
  --fc-border-color: var(--line);
  --fc-today-bg-color: var(--honey-dim);
  --fc-now-indicator-color: var(--rose);
  --fc-event-bg-color: var(--surf-2);
  --fc-event-border-color: var(--honey);
  --fc-event-text-color: var(--ink);
  --fc-highlight-color: var(--wash);
  --fc-small-font-size: 11px;
  /* FullCalendar's default resize handle is a tiny dot, easy to miss against this theme —
     thickened so the bottom edge reads as grabbable rather than just looking like a cut-off. */
  --fc-event-resizer-thickness: 8px;
  --fc-event-resizer-dot-total-width: 10px;
  --fc-event-resizer-dot-border-width: 3px;
  font-family: var(--sans);
}
/* A touch pointer is a fingertip, not a mouse cursor — the 8px resize handle above is plenty to
   aim with a mouse but easy to miss (and easy to grab the wrong event's) with a finger. */
@media (pointer: coarse) {
  #planner-calendar {
    --fc-event-resizer-thickness: 16px;
    --fc-event-resizer-dot-total-width: 18px;
    --fc-event-resizer-dot-border-width: 5px;
  }
}
#planner-calendar .fc-timegrid-slot-label-cushion,
#planner-calendar .fc-col-header-cell-cushion {
  color: var(--muted); font-size: 11px;
}
#planner-calendar .fc-col-header-cell-cushion { text-transform: capitalize; font-weight: 600; }
#planner-calendar .fc-timegrid-now-indicator-line { border-color: var(--rose); }
#planner-calendar .fc-timegrid-now-indicator-arrow { border-color: var(--rose); color: var(--rose); }

#planner-calendar .fc-event {
  /* The full border is spelled out explicitly (not left to --fc-event-border-color alone):
     the FullCalendar "Standard" bundle injects its own <style> at runtime, after notte.css has
     already loaded, and its own rules were winning the cascade tie against a bare CSS-variable
     assignment — the box was rendering with no visible outline except the honey accent stripe. */
  border: 1px solid var(--honey); border-left: 6px solid var(--honey);
  border-radius: 6px; padding: 2px 4px; cursor: grab;
}
/* Coloured by category, the same colours as the type badges everywhere else in the app: every
   cardiologist coral, every MMG honey, a place steel blue. The rep reads a week by what kind of
   call each slot is, and a colour that means one thing on the badge and another on the grid would
   have to be learnt twice. The palette's theme variables already carry a light and a dark value,
   so nothing here needs a theme switch of its own.
   Only the two variables are set, never border-color itself: that leaves the alert outline and the
   status stripe below free to win, whatever order the rules sit in. An unrecognised code gets the
   same neutral grey its badge has. */
#planner-calendar .fc-event, .doctor-chip, .agenda-item {
  --doctor-bg: var(--wash);
  --doctor-line: var(--faint);
  background: var(--doctor-bg);
  border-color: var(--doctor-line);
}
#planner-calendar .fc-event.fc-cat-mmg, .doctor-chip.fc-cat-mmg, .agenda-item.fc-cat-mmg { --doctor-bg: var(--honey-dim); --doctor-line: var(--honey); }
#planner-calendar .fc-event.fc-cat-pls, .doctor-chip.fc-cat-pls, .agenda-item.fc-cat-pls { --doctor-bg: var(--mint-dim); --doctor-line: var(--mint); }
#planner-calendar .fc-event.fc-cat-aic, .doctor-chip.fc-cat-aic, .agenda-item.fc-cat-aic { --doctor-bg: var(--pink-dim); --doctor-line: var(--pink); }
#planner-calendar .fc-event.fc-cat-car, .doctor-chip.fc-cat-car, .agenda-item.fc-cat-car { --doctor-bg: var(--coral-dim); --doctor-line: var(--coral); }
#planner-calendar .fc-event.fc-cat-dia, .doctor-chip.fc-cat-dia, .agenda-item.fc-cat-dia { --doctor-bg: var(--violet-dim); --doctor-line: var(--violet); }
#planner-calendar .fc-event.fc-cat-enc, .doctor-chip.fc-cat-enc, .agenda-item.fc-cat-enc { --doctor-bg: var(--sky-dim); --doctor-line: var(--sky); }
#planner-calendar .fc-event.fc-cat-ger, .doctor-chip.fc-cat-ger, .agenda-item.fc-cat-ger { --doctor-bg: var(--tan-dim); --doctor-line: var(--tan); }
#planner-calendar .fc-event.fc-cat-int, .doctor-chip.fc-cat-int, .agenda-item.fc-cat-int { --doctor-bg: var(--slate-dim); --doctor-line: var(--slate); }
#planner-calendar .fc-event.fc-cat-ipr, .doctor-chip.fc-cat-ipr, .agenda-item.fc-cat-ipr { --doctor-bg: var(--magenta-dim); --doctor-line: var(--magenta); }
#planner-calendar .fc-event.fc-cat-lip, .doctor-chip.fc-cat-lip, .agenda-item.fc-cat-lip { --doctor-bg: var(--olive-dim); --doctor-line: var(--olive); }
#planner-calendar .fc-event.fc-cat-meu, .doctor-chip.fc-cat-meu, .agenda-item.fc-cat-meu { --doctor-bg: var(--teal-dim); --doctor-line: var(--teal); }
#planner-calendar .fc-event.fc-cat-nef, .doctor-chip.fc-cat-nef, .agenda-item.fc-cat-nef { --doctor-bg: var(--cyan-dim); --doctor-line: var(--cyan); }
#planner-calendar .fc-event.fc-cat-pne, .doctor-chip.fc-cat-pne, .agenda-item.fc-cat-pne { --doctor-bg: var(--indigo-dim); --doctor-line: var(--indigo); }
#planner-calendar .fc-event.fc-cat-str, .doctor-chip.fc-cat-str, .agenda-item.fc-cat-str { --doctor-bg: var(--steel-dim); --doctor-line: var(--steel); }
/* A warning (overlap, outside the surgery's hours, too soon after the last visit) outlines the
   chip in red on three sides and turns its time line red and bold, with a larger ⚠ — but leaves
   the thick left stripe in the category colour: that stripe says who, the red says what is wrong,
   and one should not erase the other. */
#planner-calendar .fc-event.fc-event-alert-border, .doctor-chip.fc-event-alert-border {
  border-top-color: var(--rose); border-right-color: var(--rose); border-bottom-color: var(--rose);
}
#planner-calendar .fc-event.fc-event-alert-border .fc-event-time-custom,
.doctor-chip.fc-event-alert-border .fc-event-time-custom { color: var(--rose); font-weight: 700; }
/* An appointment typed in Google, still waiting for its doctor: dashed and striped rather than
   filled with a category colour — it takes the slot, but it is not a visit yet. Only variables and
   border-style are set, as for the categories above. */
#planner-calendar .fc-event.fc-event-inbox {
  --doctor-line: var(--honey);
  --doctor-bg: repeating-linear-gradient(-45deg, var(--wash) 0 6px, transparent 6px 12px);
  border-style: dashed;
  cursor: pointer;
}
#planner-calendar .fc-event.fc-event-inbox .fc-event-title-custom { font-style: italic; }
.fc-event-custom .fc-event-inbox-mark.fc-event-type-short { right: 21px; }
.fc-event-custom .fc-event-inbox-mark {
  position: absolute; right: 3px; bottom: 2px;
  font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.06em; text-transform: uppercase;
  padding: 0 4px; border-radius: 4px; line-height: 1.5;
  color: var(--honey); border: 1px solid var(--honey); background: var(--surf);
}
#planner-calendar .fc-event:active { cursor: grabbing; }
/* Read-only on touch until "Modifica" (see editMode in planner-calendar.js): the delete × goes
   away rather than sitting there as a trap for a finger that was only panning, and the cursor
   stops promising a drag. In edit mode the grid gets a honey outline, so it is obvious at a
   glance that touching it now changes the plan. */
#planner-calendar.planner-locked .fc-event-delete { display: none; }
#planner-calendar.planner-locked .fc-event,
#planner-calendar.planner-locked .fc-event:active { cursor: pointer; }
#planner-calendar.planner-editing { outline: 2px solid var(--honey); outline-offset: 4px; border-radius: 6px; }
/* While editing on touch, a finger that lands on an appointment never scrolls the page. This has
   to be decided before the gesture begins — the browser reads touch-action at touchstart. The
   earlier attempt, cancelling touchmove once the drag had started, came too late: a finger held
   for the long press is never perfectly still, those small moves were not cancelled, the browser
   began panning, and from that point it refuses to let a script stop the scroll for the rest of
   the gesture. So the appointment slid with the page, exactly as reported.
   pinch-zoom where the browser supports it (one finger no longer pans, two fingers still zoom);
   none as the fallback where it does not. Only appointments, only in the time grid: empty slots
   still scroll, so the week can be moved by swiping between appointments, and read-only mode is
   untouched. */
#planner-calendar.planner-editing .fc-timegrid-event {
  touch-action: none;
  touch-action: pinch-zoom;
}
/* While an appointment is being dragged on touch (see setDragging in planner-calendar.js): no
   pull-to-refresh, no rubber-band bounce at the page edge. */
html.planner-dragging,
html.planner-dragging body { overscroll-behavior: none; }

/* Pencil while read-only, tick while editing — see the button in WeekPlanner.razor. */
.planner-edit-toggle:not(.btn-primary) .ico-done,
.planner-edit-toggle.btn-primary .ico-edit { display: none; }
.planner-edit-hint {
  margin: -8px 0 14px; padding: 8px 12px; border-radius: var(--r-sm);
  background: var(--honey-dim); color: var(--ink-2); font-size: 13px;
}
/* Month view isn't draggable (see views.dayGridMonth in planner-calendar.js), so the grab cursor
   above would be a lie there. */
#planner-calendar .fc-daygrid-event { cursor: pointer; padding: 1px 4px; }

/* The candidate list in the add dialog: opening hours under each name, and a plain warning when
   the one being considered is shut at the hour the rep clicked on. */
/* Written through .planner-candidate: the plain "span" rule above sets display and colour for
   every span in the card and would otherwise outrank a bare class selector here. */
.planner-candidate .planner-candidate-hours {
  display: grid; gap: 1px; margin-top: 4px; font-size: 11.5px; color: var(--ink-2);
}
.planner-candidate .planner-candidate-hours.muted { color: var(--faint); font-style: italic; }
.planner-candidate .planner-hours-line b { font-weight: 600; color: var(--muted); }
.planner-candidate .planner-candidate-warn {
  display: inline-flex; align-items: center; gap: 4px; margin-top: 4px;
  font-size: 11.5px; font-weight: 600; color: var(--rose);
}
.planner-candidate-closed { border-color: var(--rose); }

.fc-event-custom { overflow: hidden; height: 100%; position: relative; }
/* Side by side (see slotEventOverlap in planner-calendar.js) a chip can be half a column wide, or
   less on a phone. Rather than squeezing everything into it, each chip is measured on its own and
   drops what matters least first: the address, then the type code in the corner, then the second
   line of the time range. What is left — the start time and the name — is what tells one
   appointment from another. */
.fc-timegrid-event { container-type: inline-size; }
@container (max-width: 165px) {
  .fc-event-custom .fc-event-address { display: none; }
  .fc-event-custom .fc-event-title-custom { font-size: 11.5px; padding-right: 0; }
}
@container (max-width: 140px) {
  .fc-event-custom .fc-event-end-time,
  .fc-event-custom .fc-event-type,
  .fc-event-custom .fc-event-note { display: none; }
  .fc-event-custom .fc-event-time-custom { font-size: 9.5px; }
}
/* Narrower still — three at the same hour on a phone: only the start time and the name. The
   delete × shrinks but stays: it had been dropped here to leave the name its room, and two
   appointments at the same hour — exactly the ones that end up this narrow — were then the ones
   that could not be deleted from the grid at all. It sits in the corner, and the name keeps clear
   of it rather than running underneath. */
@container (max-width: 96px) {
  .fc-event-custom .fc-event-delete { width: 14px; height: 14px; line-height: 12px; font-size: 11px; }
  .fc-event-custom .fc-event-title-custom { font-size: 11px; padding-right: 15px; }
}
/* Two side by side in a phone's week view leave about 40px each: the start time no longer fits,
   and where the chip sits in the grid already says the hour. The name stays, and so does the ⚠ —
   the one thing the position cannot tell. */
@container (max-width: 58px) {
  .fc-event-custom .fc-event-start-time { display: none; }
  .fc-event-custom .fc-event-time-custom:empty { display: none; }
  .fc-event-custom .fc-event-title-custom { font-size: 10.5px; line-height: 1.2; }
}
/* The type code in the chip's bottom-right corner — the type badge, shrunk to sit in a chip.
   The badge's own background is translucent; an opaque layer underneath keeps a line of address
   or note running beneath it from showing through. */
.fc-event-custom .fc-event-type {
  position: absolute; right: 3px; bottom: 2px; isolation: isolate;
  font-size: 8.5px; padding: 0 4px; border-radius: 4px; letter-spacing: 0.06em; line-height: 1.5;
}
.fc-event-custom .fc-event-type::before {
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--surf);
}
/* Short chips: left of the delete × instead of under it — the type code and the "da abbinare" mark. */
.fc-event-custom .fc-event-type-short { right: 21px; }
/* The count of doctors inside a place, ahead of its name on the chip.
   Small and dark so it reads as a tally rather than as part of the name; an empty container wears
   the warning's colours instead, because a visit to a hospital with nobody written down yet is
   still to be planned. */
.fc-event-count {
  display: inline-flex; align-items: center; gap: 2px; vertical-align: 1px;
  margin-right: 4px; padding: 0 4px; border-radius: 999px;
  background: var(--ink); color: var(--bg);
  font-size: 9.5px; font-weight: 700; line-height: 14px;
}
.fc-event-count svg { width: 9px; height: 9px; fill: none; stroke: currentColor; stroke-width: 2.6; }
.fc-event-count-empty { background: var(--rose); color: #fff; }
/* ---------- the drawer over the grid ---------- */
/* A panel that slides in from the right edge, over the page. It was a column beside the week
   first, and that was wrong: it took the width the grid needed, and Friday ended up squeezed to
   plan a visit that was never going to be dropped on it. Off the screen entirely when closed,
   except the tab that pulls it out. */
.planner-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 40;
  width: min(360px, 92vw); display: flex; flex-direction: column;
  background: var(--surf); border-left: 1px solid var(--line);
  box-shadow: -18px 0 44px rgba(0, 0, 0, 0.18);
  transform: translateX(100%); transition: transform 0.18s ease;
}
.planner-drawer:not(.is-collapsed) { transform: none; }
.planner-drawer.is-collapsed .planner-drawer-body { display: none; }
/* The tab: the only part of the drawer on screen when it is closed, and its way back out. Sits
   just off the panel's left edge, so it is the handle in both states. */
.planner-drawer-toggle {
  position: absolute; left: -34px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: 6px; padding: 14px 8px;
  writing-mode: vertical-rl;
  background: var(--surf); color: var(--ink); font: inherit; font-size: 12.5px; font-weight: 600;
  border: 1px solid var(--line); border-right: 0; border-radius: 10px 0 0 10px;
  box-shadow: -8px 0 20px rgba(0, 0, 0, 0.12);
  cursor: pointer;
}
.planner-drawer-toggle:hover { color: var(--honey); }
.planner-drawer-chevron { width: 15px; height: 15px; flex-shrink: 0; transform: rotate(90deg); }
.planner-drawer.is-collapsed .planner-drawer-chevron { transform: rotate(-90deg); }
.planner-drawer-body { display: grid; gap: 10px; padding: 12px; overflow-y: auto; }
.planner-drawer-search { display: flex; gap: 6px; }
.planner-drawer-search .input { width: 100%; }
.planner-drawer-results { display: grid; gap: 10px; }
/* The cards of "Cerca", in a column a third as wide: the same card, with the room it has taken
   away rather than a second design to keep in step. */
.planner-drawer .doctor-card { padding: 12px; cursor: grab; }
.planner-drawer .doctor-card:active { cursor: grabbing; }
.planner-drawer .doctor-card h2 { font-size: 14px; }
.planner-drawer .doctor-card-registry { display: none; }
.planner-drag-card { touch-action: pan-y; }
/* Mid-drag: FullCalendar carries a copy of the card across the page (cloned, appended to <body>,
   width and height pinned inline to the card's own). A whole card — registry and all, since out of
   the drawer its drawer-only rules no longer apply — covered the very hours it was being dropped
   on. The copy is cut down to a chip instead: the name and the type code, the calendar's own shape.
   The !important is against FullCalendar's inline width and height, nothing else. The transform
   puts the chip's corner at the pointer rather than wherever the card's corner was: the card is
   tall, and grabbed halfway down, a chip left at its top-left would float far above the finger.
   --grab-x/--grab-y are set on the card at pointerdown (planner-calendar.js) and travel with the
   clone, since cloneNode copies the style attribute. */
.planner-drag-card.fc-event-dragging {
  width: auto !important; height: auto !important; max-width: 260px;
  transform: translate(var(--grab-x, 0px), var(--grab-y, 0px));
}
.planner-drag-card.fc-event-dragging .doctor-card {
  padding: 6px 10px 6px 8px; border-radius: 6px;
  border: 1px solid var(--honey); border-left: 6px solid var(--honey);
  background: var(--surf); box-shadow: 0 10px 24px rgba(0, 0, 0, 0.2);
}
.planner-drag-card.fc-event-dragging .doctor-card > :not(.doctor-card-head),
.planner-drag-card.fc-event-dragging .avatar,
.planner-drag-card.fc-event-dragging .doctor-card-identity p,
.planner-drag-card.fc-event-dragging .type-badge.mine,
.planner-drag-card.fc-event-dragging .type-badge.mine-add,
.planner-drag-card.fc-event-dragging .type-badge.local { display: none !important; }
.planner-drag-card.fc-event-dragging .doctor-card-head { gap: 8px; }
.planner-drag-card.fc-event-dragging .doctor-card-identity h2 { font-size: 12.5px; margin: 0; white-space: nowrap; }
.planner-drag-card.fc-event-dragging .type-badge { font-size: 9px; padding: 1px 5px; }

/* The doctors of a place, in its dialog: each one the chip it would be on the grid (see
   .doctor-chip), so a list read here reads the way the week does. */
.structure-doctors { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
/* A chip outside the calendar: the same box the grid draws, given the room it never has there —
   the border and the category colour come from the rules above, shared with .fc-event. Its own
   height, since nothing here is measured against an hour of the grid, and no container query:
   the dialog is as wide as the dialog, so nothing has to be dropped to fit. */
.doctor-chip {
  position: relative; overflow: hidden;
  border: 1px solid var(--doctor-line); border-left: 6px solid var(--doctor-line);
  border-radius: 6px; padding: 5px 7px 6px;
}
/* The whole chip opens the doctor: a transparent button laid over it, under the ✕ so that taking
   someone off the list is never read as asking to open them. */
.doctor-chip-open {
  position: absolute; inset: 0; z-index: 1;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.doctor-chip:hover { border-color: var(--honey); }
.doctor-chip .fc-event-title-custom { font-size: 13px; padding-right: 26px; }
.doctor-chip .fc-event-address { font-size: 11.5px; }
.doctor-chip .fc-event-time-custom { font-size: 10.5px; }
.doctor-chip .fc-event-type { font-size: 9px; }
/* The ✕ that takes a doctor off a place: the calendar's grey × (see .icon-x), in the chip's corner
   and above the chip's own button, with its confirmation beside it. */
.doctor-chip .corner-action { top: 4px; right: 4px; }
.doctor-chip .icon-x { width: 22px; height: 22px; font-size: 11px; }

/* A planned visit's note on its chip: two lines at most, the rest in the visit dialog. */
.fc-event-note {
  margin-top: 2px; font-size: 10.5px; font-style: italic; line-height: 1.3; color: var(--ink-2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.fc-event-note-flag { color: var(--ink-2); }
/* The visit dialog's content, inset like the add dialog's (#planner-add-dialog-slot): without it
   the date, the field and the buttons ran flush against the dialog's edges. */
.planner-visit-body { padding: 14px 18px 18px; display: grid; gap: 10px; }
.planner-visit-body .planner-note-form { margin: 0; }
.planner-visit-when { color: var(--muted); font-size: 13px; }
.planner-visit-dialog .planner-visit-type { display: inline-block; vertical-align: 2px; margin-right: 8px; font-size: 9.5px; padding: 2px 6px; }
.planner-visit-warnings {
  list-style: none; margin: 0; padding: 8px 12px; border-radius: var(--r-sm);
  background: var(--rose-dim); color: var(--rose); font-size: 13px; font-weight: 600; display: grid; gap: 3px;
}
/* The compact month-view chip: a single line, not the tall time-grid card — no clipped height,
   no reserved space for a delete button it doesn't have. */
.fc-event-custom-month {
  height: auto; overflow: hidden; position: static;
  display: flex; align-items: baseline; gap: 3px; white-space: nowrap;
}
.fc-event-custom-month .fc-event-time-custom { font-size: 9.5px; }
.fc-event-custom-month .fc-event-title-custom {
  font-size: 11px; padding-right: 0; overflow: hidden; text-overflow: ellipsis;
}
.fc-event-time-custom {
  font-size: 10px; font-family: var(--mono); color: var(--honey); line-height: 1.3;
}
/* A warning icon ahead of the time instead of coloring the whole event box — see
   buildEventContent's own remark on why. */
.fc-event-alert { margin-right: 4px; font-size: 13.5px; line-height: 1; vertical-align: -1px; font-weight: 700; }
.fc-event-alert-conflict, .fc-event-alert-recent, .fc-event-alert-hours { color: var(--rose); }
.fc-event-title-custom { font-size: 12px; font-weight: 600; line-height: 1.25; padding-right: 16px; }
.fc-event-address { font-size: 10.5px; color: var(--muted); line-height: 1.3; }
.fc-event-delete {
  /* Fully inside the box, not straddling its edge: .fc-event-custom clips at its own bounds
     (overflow: hidden, needed to keep long titles/addresses from spilling out), and a button
     positioned half outside that boundary gets its outer half sheared off rather than clipped
     to a smaller circle. */
  position: absolute; top: 2px; right: 2px; width: 16px; height: 16px; line-height: 14px;
  text-align: center; border-radius: 50%; background: var(--surf-3); color: var(--muted);
  border: none; font-size: 13px; cursor: pointer; padding: 0;
}
.fc-event-delete:hover { background: var(--rose); color: #fff; }

.today-slot {
  display: flex; align-items: center; gap: 12px;
  background: var(--surf); border: 1px solid rgba(233, 166, 72, 0.28); border-radius: var(--r-lg);
  padding: 12px 14px; margin-bottom: 8px;
}
.today-slot .avatar { width: 38px; height: 38px; border-radius: 12px; }
.today-slot-actions { display: flex; gap: 7px; flex-shrink: 0; }

/* Settings: the two times of the working day side by side, the save button under them on a phone. */
.working-day-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.working-day-form .field { flex: 1 1 130px; }
@media (pointer: coarse) {
  .working-day-form .input { font-size: 16px; }
}
