  .err{margin:16px 20px; padding:12px 14px; background:#FDEDEC; border:1px solid #F5C6C4; border-radius:10px; color:#8A2A24; display:none}
  [data-theme="dark"] .err{background:#2A1F1F; border-color:#5B3C3C; color:#FF8888; display:none}
  @media(prefers-color-scheme:dark){
    :root:not([data-theme="light"]) .err{background:#2A1F1F; border-color:#5B3C3C; color:#FF8888; display:none}
  }
  .modal-bg{position:fixed; inset:0; background:rgba(16,24,37,.45); display:flex; align-items:center;
    justify-content:center; z-index:50; padding:16px}
  /* Frosted-glass backdrop for the Booking Details, New Booking, and User Management modals -
     blurs the calendar behind them instead of just dimming it, so the modal itself reads clearer. */
  .modal-bg.blur-bg{backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px)}
  /* Capped to the viewport and scrollable on its own: .modal-bg is a fixed, centered flex box, so
     a modal taller than the screen (the New Booking form with recurrence open, on a phone) used to
     overflow equally past the top and bottom edges with no way to reach either end. */
  .modal{background:var(--card); border:2px solid var(--accent); border-radius:12px; padding:20px; width:100%; max-width:400px;
    max-height:calc(100vh - 32px); max-height:calc(100dvh - 32px); overflow-y:auto; overscroll-behavior:contain}
  .modal.modal-lg{max-width:640px; padding:28px}
  @media(max-width:480px){.modal{padding:14px} .modal.modal-lg{padding:16px}}
  .modal h3{margin:0 0 4px; font-family:'Space Grotesk',sans-serif; font-size:20px}
  .modal-title-row{display:flex; align-items:flex-start; justify-content:space-between; gap:12px}
  /* One red outlined close control for every modal and sheet. `button.modal-close-btn` has enough
     specificity to keep its dimensions when it is combined with a sheet's generic icon class. */
  .compact-close-btn,button.modal-close-btn{box-sizing:border-box; width:32px; height:32px; padding:0; flex:0 0 auto;
    display:inline-flex; align-items:center; justify-content:center; border:1px solid #C0392B;
    border-radius:8px; background:transparent; color:#C0392B; font-size:16px; line-height:1; cursor:pointer}
  .compact-close-btn:hover,button.modal-close-btn:hover{background:#C0392B; border-color:#C0392B; color:#fff}
  /* One fixed size for every panel's "‹ Back" button, rather than each panel's markup setting (or
     forgetting to set) its own padding/font-size - so the button is identically wide everywhere
     and the heading beside it always starts from the same x position. No size override beyond
     that: the plain default button size (base.css) is what every panel's bottom-right Save button
     uses too (see the panels' own modal-actions), so Back and Save end up the same size for free.
     display:flex+align-items/justify-content centers the "‹" and "Back" as a unit regardless of
     that glyph's own ascent/descent, rather than leaning on text-align/line-height alone. */
  .back-btn{flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; gap:4px;
    border-color:var(--accent)}
  .cancel-btn{border-color:var(--accent) !important}
  .modal .sub{margin:4px 0 0; color:var(--muted)}
  .field{margin:12px 0}
  .field label{display:block; font-size:12px; font-weight:600; color:var(--muted); margin-bottom:5px}
  .field input,.field select{width:100%; padding:9px 11px; border:1px solid var(--line); border-radius:8px; background:var(--card); color:var(--ink)}
  .field input::placeholder{color:var(--muted)}
  /* A field that's shown but can't be edited (the profile form's own email row) - background:var(--paper)
     is the same "recessed" surface disabled/inactive UI elsewhere in the app already uses, so it reads as
     "here, but not editable" without needing separate explanatory copy next to it. */
  .field input:disabled{background:var(--paper); color:var(--muted); cursor:not-allowed}
  /* The avatar editor's zoom slider - the one range input in the app. accent-color tints the
     browser's own native slider to match the app's palette instead of leaving it OS-default blue
     (or grey), without needing to rebuild a slider from scratch. */
  .field input[type="range"]{padding:0; accent-color:var(--accent);}
  /* Reveal control on a password box - the wrapper is added around the input at runtime (see
     addPasswordToggles), so one rule covers the sign-in page, the set-password page and the change-password
     form alike. !important on the padding because those inputs carry their own inline padding, and the text
     has to stop short of the button rather than run under it. */
  .pw-wrap{position:relative; display:block}
  .pw-wrap input{padding-right:40px !important}
  .pw-eye{position:absolute; top:50%; right:5px; transform:translateY(-50%); width:30px; height:30px;
    display:flex; align-items:center; justify-content:center; padding:0; background:transparent; border:none;
    border-radius:50%; color:var(--muted); cursor:pointer}
  .pw-eye:hover{color:var(--accent); background:var(--paper)}
  .pw-eye svg{width:18px; height:18px; display:block}
  /* A divider above every panel's own Save/Cancel/Confirm/Add row, separating it from whatever
     content sits above (form fields, a message, a grid of choices) - one rule here instead of each
     panel drawing its own <hr>, so every modal-actions row gets it for free and stays consistent. */
  .modal-actions{display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-end; margin-top:16px;
    padding-top:16px; border-top:1px solid var(--line)}
  /* Same divider as .modal-actions' own border-top, for an action row that stays left-aligned
     (Add user, Create a workspace, Send/Update reply) instead of using modal-actions' flex-end
     layout - an <hr> rather than a border-top so it works with these sections' plain markup. */
  .action-divider{border:none; border-top:1px solid var(--line); margin:16px 0}
  .dt-row{display:grid; grid-template-columns:1.3fr 0.7fr 1.3fr; gap:14px}
  @media(max-width:600px){.dt-row{grid-template-columns:1fr}}
  .two-col-row{display:grid; grid-template-columns:1fr 1fr; gap:10px}
  .au-grid-2{display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:10px}
  .au-grid-21{display:grid; grid-template-columns:2fr 1fr; gap:10px; margin-bottom:10px}
  @media(max-width:600px){.two-col-row,.au-grid-2,.au-grid-21{grid-template-columns:1fr}}
  .modal-section{margin-top:22px; padding-top:20px; border-top:1px solid var(--line)}
  .recur-box{margin-top:14px; padding:16px; border:1px solid var(--line); border-radius:10px; background:var(--paper)}
  .recur-box .field:first-child{margin-top:0}
  .recur-toggle{display:inline-flex; align-items:center; gap:6px; border-radius:999px; padding:8px 14px; border:1px solid var(--line); background:var(--card); color:var(--ink); cursor:pointer; font-weight:600; font-size:12px}
  .recur-toggle:hover{border-color:var(--accent); color:var(--accent)}
  .recur-toggle.on{background:var(--accent); color:#fff; border-color:var(--accent)}
  .dow-row{display:flex; gap:6px; margin-top:10px}
  .dow-circle{width:32px; height:32px; flex-shrink:0; border-radius:50%; border:1px solid var(--line); background:var(--card); color:var(--ink); font-weight:600; font-size:12px; cursor:pointer; display:flex; align-items:center; justify-content:center; padding:0}
  .dow-circle:hover{border-color:var(--accent)}
  .dow-circle.on{background:var(--accent); color:#fff; border-color:var(--accent)}
  .recur-delete{background:transparent; border:none; color:var(--muted); cursor:pointer; padding:6px; font-size:15px; border-radius:6px}
  .recur-delete:hover{color:#C0392B}
  .dropdown-menu{position:absolute; bottom:calc(100% + 4px); right:0; background:var(--card); border:1px solid var(--line); border-radius:8px; box-shadow:0 4px 16px rgba(0,0,0,.2); min-width:220px; max-width:calc(100vw - 32px); z-index:70; overflow:hidden;}
  @media(max-width:480px){.dropdown-menu{min-width:160px}}

  .dropdown-menu div{padding:10px 14px; font-size:13px; color:var(--ink); cursor:pointer; white-space:nowrap;}
  .dropdown-menu div:hover{background:var(--paper);}

  /* Booking-series Edit/Delete menus belong to the dialog's action row. Keep them in normal flow
     below their own buttons so opening one grows the modal downward; the generic absolute menu
     would open upward and right-align even the left-side Delete menu, pushing it outside the modal. */
  .booking-action-wrap{display:flex; flex-direction:column; align-items:flex-start;}
  .booking-action-wrap.booking-action-right{align-items:flex-end;}
  .dropdown-menu.booking-action-menu{position:static; margin-top:4px; min-width:220px; max-width:min(280px, calc(100vw - 60px)); border-color:var(--accent);}
  .dropdown-menu.booking-action-menu div+div{border-top:1px solid var(--line);}
  @media(max-width:480px){.dropdown-menu.booking-action-menu{min-width:160px;}}

  /* A .dropdown-menu that groups its rows under sticky category headers, with a checkmark on
     whichever one is current - the room/resource picker (header tab strip) and each side of the
     Split view picker (calendar.js) both use this, mirroring the account menu's own grouped
     timezone list (auth.css's .tz-list). Needs its own overflow (the plain .dropdown-menu clips
     instead of scrolling) since a resource list can run well past one screen's height. */
  .dropdown-menu.grp-list{overflow-y:auto; overflow-x:hidden; max-height:min(50dvh, 320px);}
  /* Tinted (not plain var(--card)) so a category header reads as its own distinct kind of row at a
     glance - a label, never a pickable option - rather than looking like just another list item
     that happens to be bold and blue, which is easy to confuse with .grp-current below now that
     both use the same accent blue for their text/fill. color-mix keeps this correct in both themes
     without a second set of hardcoded values (same technique auth.css's .tz-current:hover already
     uses). */
  .grp-list .grp-region{position:sticky; top:0; z-index:1; padding:9px 14px;
    background:color-mix(in srgb, var(--accent) 12%, var(--card));
    font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--accent);
    text-align:center; cursor:default;}
  .grp-list .grp-region:hover{background:color-mix(in srgb, var(--accent) 12%, var(--card))}
  /* A thin divider above every category EXCEPT the first (:not(:first-child) - each .grp-region is
     a direct sibling of the previous group's own rows, so this only ever excludes the very first
     header in the whole list) closes off the previous group before the next label starts, rather
     than the two categories just running together with nothing but a font-weight/case change
     between them. Flush against the row above it - no margin-top - so it reads as a clean line
     between the two groups rather than a stray band of empty space sitting above it. */
  .grp-list .grp-region:not(:first-child){border-top:1px solid var(--line);}
  /* Every pickable row (not the region header above, which isn't clickable) is centered - matching
     the region headers above them, rather than left-aligned text sitting under a centered label -
     and reserves a transparent border up front so hovering it - a blue border, the same
     accent-border treatment the header's own room-picker tab already gets on hover (.tab:hover,
     calendar.css) - never shifts the row by suddenly adding one. .dropdown-menu's own plain
     gray-background hover (further up this file) would otherwise still apply here too - overridden
     back to transparent so the border is the only hover cue in this particular list. Excludes
     .grp-current (the currently-selected room) - not just because it should stay solid blue rather
     than merely bordering, but because a plain :hover here would otherwise actually WIN over
     .grp-current:hover below despite looking less specific at a glance: with an equal class count
     on both sides, the extra `div` element in this selector counts too, and a selected room being
     hovered is exactly when someone's most likely to have their mouse sitting - so this can't be
     left to a specificity tie-break. */
  .grp-list div:not(.grp-region){border:1px solid transparent; text-align:center;}
  .grp-list div:not(.grp-region):not(.grp-current):hover{background:transparent; border-color:var(--accent);}
  .grp-list .grp-current{background:var(--accent); color:#fff; font-weight:700; border-color:var(--accent);}
  .grp-list .grp-current:hover{background:var(--accent); border-color:var(--accent);}

  /* Above every dialog layer, including #alertHost's - a toast is the outcome of an action and shouldn't
     end up dimmed behind the dialog that started it. Top-center (not bottom) and outlined in red so it
     can't be missed - every toast() call uses this, whether it's reporting an error, a booking/event
     change, or a user/role change (see admin.js, booking.js, auth.js). Sits just below the header
     (--hdr-h, published by publishHeaderHeight - see auth.js) rather than at a fixed distance from the
     viewport top, since the header itself is pinned there and would otherwise sit under it.
     --card/--ink (not a hardcoded dark pill) so it matches the rest of the surface in light mode too -
     white with dark text there, the same dark card it always was in dark mode - only the red border is
     fixed across both themes, since that's the deliberate accent that makes it stand out. */
  .toast{position:fixed; top:calc(var(--hdr-h, 60px) + 12px); left:50%; transform:translateX(-50%);
    background:var(--card); color:var(--ink); border:2px solid #C0392B; padding:10px 16px; border-radius:10px;
    z-index:100; font-weight:500; max-width:calc(100vw - 32px); box-sizing:border-box; text-align:left;
    box-shadow:0 4px 16px rgba(0,0,0,.18);}
  /* The confirm/notice layer, above the ordinary modals' z-index:50 (see #alertHost). */
  #alertHost .modal-bg{z-index:75}

  /* Floating "Support" button - built and wired up at runtime by public/js/support.js, shown only
     on the login/signup pages (placeButton hides it entirely once the calendar page is showing -
     Support lives in the account sheet there instead, see auth.js). Same 32px circle as .icon-btn
     (the header's own Exit/Sign out button) - not a bigger, separate "FAB" size. Sits below the
     ordinary .modal-bg layer (z-index:40 < 50) so the panel this button raises still visibly rises
     above it. */
  .support-fab{width:32px; height:32px; padding:0; flex-shrink:0;
    border-radius:50%; background:var(--accent); border:1px solid var(--accent); color:#fff;
    display:flex; align-items:center; justify-content:center; cursor:pointer;}
  .support-fab:hover{opacity:.88; color:#fff}
  .support-fab svg{width:17px; height:17px}
  .support-fab-floating{position:fixed; right:20px; bottom:20px; z-index:40; box-shadow:0 4px 12px rgba(0,0,0,.28);}
  /* Unread-reply notification dot - shown/hidden by refreshUnreadBadge() (support.js), polling
     GET /api/support/unread-count. The 2px ring in --card keeps it readable against whatever's
     behind the floating button, in both themes. */
  /* display:inline-flex + align/justify-center (not the old line-height/text-align approach) is
     what actually centers the digit - a plain <span> ignores width/height/min-width entirely
     (they only apply to block-level or flex/grid boxes), so without this the "circle" was really
     just however big the text+padding happened to render, off-center more often than not. Same fix
     .sr-badge below already used. */
  .support-fab-badge{position:absolute; top:-3px; right:-3px; min-width:16px; height:16px; padding:0 3px;
    border-radius:999px; background:#C0392B; color:#fff; font-size:10px; font-weight:700;
    display:inline-flex; align-items:center; justify-content:center; box-shadow:0 0 0 2px var(--card);}
  /* Same red "unread" dot, inline instead of absolutely-positioned - the "My tickets" row in the
     account menu (auth.js), next to the Support button's own badge above. */
  .sr-badge{display:inline-flex; align-items:center; justify-content:center; min-width:16px; height:16px;
    padding:0 4px; margin-left:6px; border-radius:999px; background:#C0392B; color:#fff; font-size:10px; font-weight:700;}
  /* Groups one host workspace/organization together with its own tenants (User management,
     Workspace management, Support tickets - each panel that nests tenants under their host) inside
     one border, same width/radius as the app's own modal panels (.modal, 2px solid), so a cluster
     of related companies reads as one unit rather than a plain unbroken list. var(--accent) here
     is only ever the fallback for a company with no assigned color yet - every actual call site
     overrides border-color inline with that host's own companyColor, the same color already
     marking its name, so a cluster's border tells you which company it is at a glance. A host with
     no tenants at all still gets one of these, just around itself alone - every top-level entry in
     these panels is wrapped the same way, tenants or not. */
  .host-cluster{border:2px solid var(--accent); border-radius:12px; padding:4px; margin-bottom:10px;
    display:flex; flex-direction:column; gap:8px;}
  .support-option{display:flex; align-items:center; gap:12px; width:100%; box-sizing:border-box;
    padding:14px; margin-bottom:10px; background:var(--paper); border:1px solid var(--line);
    border-radius:10px; color:var(--ink); text-align:left; text-decoration:none; cursor:pointer;
    font:inherit}
  .support-option:last-child{margin-bottom:0}
  .support-option:hover{border-color:var(--accent)}
  .support-option .support-option-icon{flex-shrink:0; width:36px; height:36px; border-radius:50%;
    background:var(--card); border:1px solid var(--line); display:flex; align-items:center;
    justify-content:center; color:var(--accent)}
  .support-option .support-option-icon svg{width:18px; height:18px}
  .support-option strong{display:block; font-size:13px}
  .support-option small{display:block; color:var(--muted); font-size:12px; margin-top:2px}
  .support-success{text-align:center; padding:8px 0}
  .support-success .support-success-icon{font-size:32px; margin-bottom:10px}
