  @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;700&family=Inter:wght@400;500;600&display=swap');
  :root{
    --ink:#101825; --muted:#5B6472; --line:#DDE2E9; --paper:#F2F4F7; --card:#fff; --accent:#2A52E2;
    color-scheme:light;
  }
  @media(prefers-color-scheme:dark){
    :root:not([data-theme="light"]){
      --ink:#F0F2F5; --muted:#A8B0B8; --line:#2C3E50; --paper:#0D1117; --card:#1A1E28; --accent:#4A7FFF;
      color-scheme:dark;
    }
  }
  [data-theme="dark"]{
    --ink:#F0F2F5; --muted:#A8B0B8; --line:#2C3E50; --paper:#0D1117; --card:#1A1E28; --accent:#4A7FFF;
    color-scheme:dark;
  }
  *{box-sizing:border-box}
  *{scrollbar-width:thin; scrollbar-color:var(--line) var(--paper)}
  *::-webkit-scrollbar{width:10px; height:10px}
  *::-webkit-scrollbar-track{background:var(--paper)}
  *::-webkit-scrollbar-thumb{background:var(--line); border-radius:6px}
  *::-webkit-scrollbar-thumb:hover{background:var(--muted)}
  html,body{margin:0; height:100%; background:var(--paper); color:var(--ink); font:14px 'Inter',system-ui,sans-serif}
  body{display:flex; flex-direction:column}
  /* Three columns - brand + room tabs, the clock, then theme + account - with the two outer ones equal
     so the clock sits centred on the header itself rather than in whatever space happens to be left.
     A real column, not absolute centring, so it can never end up under the tabs or the account button. */
  header{display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr); gap:10px; align-items:center;
    padding:12px 16px; background:var(--card); border-bottom:1px solid var(--line); position:relative}
  /* Placed by column rather than left to auto-placement: the clock is display:none until sign-in, and a
     display:none grid item is skipped entirely - which slid the theme button up into the middle column
     and left it sitting centred on the sign-in page. */
  .hdr-left{grid-column:1; display:flex; gap:12px; align-items:center; min-width:0}
  .hdr-brand{display:flex; gap:12px; align-items:center; flex-shrink:0}
  #headerClock{grid-column:2}
  .hdr-right{grid-column:3; display:flex; gap:12px; align-items:center; justify-content:flex-end}
  @media(max-width:1000px){header{padding:10px 12px; gap:8px}}
  /* Whether the signed-in-only header pieces are shown is driven by a class on <html> (set at the
     same points that used to set inline display on each one), so the phone rules at the bottom of
     this stylesheet can re-place them: an inline display:flex set from JS wins over any stylesheet
     rule, media query or not, which would make them impossible to move or hide per breakpoint. */
  #tabs,#acctBtn,#exitBtn{display:none}
  html.signed-in #tabs{display:flex}
  html.signed-in #acctBtn{display:inline-flex}
  html.signed-in #exitBtn{display:flex}
  /* The timezone picker, the user chip, User Management and Sign Out are never shown inline any more
     - they all live behind the account button below, at every width. They stay in the DOM, hidden,
     because that's still where the timezone list the menu offers comes from (#tz) and where the
     signed-in name is kept in sync (#actingUser). */
  #headerControls{display:none}
  /* Account button: on a wide screen a pill carrying who you're signed in as (monogram, name, role)
     the way the old inline chip did, so nothing is lost by folding four controls into one menu; on
     a narrow one just the monogram circle (see the compact-header section). */
  .acct-btn{align-items:center; gap:8px; flex-shrink:0; padding:4px 10px 4px 4px; border-radius:999px;
    background:var(--paper); font-size:12px; font-weight:600}
  .acct-btn:hover{border-color:var(--accent); color:var(--ink)}
  /* #acctMono in index.html is a plain wrapper - updateActingUserDisplay() fills it with either an
     <img class="acct-mono"> (an uploaded photo) or a <span class="acct-mono"> (initials) - see
     avatarHtml() in util.js. The wrapper carries the actual size (acct-mono-wrap) so both cases
     fill it identically via width/height:100%, rather than sizing the img/span directly. */
  .acct-mono-wrap{display:inline-flex; width:26px; height:26px; flex-shrink:0}
  .acct-mono{width:100%; height:100%; border-radius:50%; background:var(--accent); color:#fff;
    display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; letter-spacing:.3px;
    object-fit:cover}
  .acct-caret{font-size:9px; color:var(--muted)}
  /* Used as-is (no wrapper) in the account sheet and edit-profile dialogs, which rebuild their
     whole markup fresh each time they open - only the persistent header button needs the wrapper
     indirection above. object-fit:cover only matters when avatarHtml() renders this as an <img>. */
  .acct-avatar{width:38px; height:38px; flex-shrink:0; border-radius:50%; background:var(--accent); color:#fff;
    font-size:13px; font-weight:700; display:flex; align-items:center; justify-content:center; object-fit:cover}
  /* The larger preview circle in the edit-profile dialog. */
  .acct-avatar-lg{width:80px; height:80px; flex-shrink:0; border-radius:50%; background:var(--accent); color:#fff;
    font-size:26px; font-weight:700; display:flex; align-items:center; justify-content:center; object-fit:cover}
  /* The clock lives in the header's middle column at every width (on phones, in the middle of its first
     row - see the phone section). It used to sit in the calendar toolbar; centring it here is also what
     ended the room tabs' old absolute 262px alignment to "+ New Event", since an absolutely positioned
     strip and a centred column can overlap each other at narrow widths. The tabs now simply flow after
     the brand, and scroll sideways rather than wrap. */
  html.signed-in #headerClock{display:block; justify-self:center; font-variant-numeric:tabular-nums;
    font-weight:600; font-size:13px; color:var(--muted); letter-spacing:.5px; white-space:nowrap}
  #headerClock{display:none} /* app chrome - not shown over the sign-in page */
  .title{font-family:'Space Grotesk',sans-serif; font-weight:700; font-size:18px}
  @media(max-width:1000px){.title{font-size:16px}}
  @media(max-width:480px){.title{font-size:14px}}
  .title span{color:var(--accent)}
  .controls{display:flex; flex-wrap:wrap; gap:8px; align-items:center}
  @media(max-width:1000px){.controls{gap:6px}}
  .controls label{font-size:11px; color:var(--muted); font-weight:600}
  @media(max-width:1000px){.controls label{font-size:10px}}
  button,select,input{font:inherit}
  button,select{padding:8px 12px; border:1px solid var(--line); border-radius:8px; background:var(--card); color:var(--ink); font-weight:600; cursor:pointer}
  /* No browser tap flash anywhere in the app. Android Chrome paints a translucent blue wash over whatever
     was touched and holds it for a moment after the finger leaves, which on a small control reads as a
     stray blue line appearing and then going. Every tappable thing here already has its own :hover/:active
     answer, drawn instantly and in the app's own colours. */
  button,select,input,.tab,.chip,.sheet-row,[onclick]{-webkit-tap-highlight-color:transparent}
  button:active{filter:brightness(1.15)}
  /* Controls aren't prose: a tap that lands slightly long shouldn't start selecting their labels and pop
     the selection handles. Deliberately listed one by one rather than set on everything, so the things
     worth copying - a booking's details, an account's address, the temp password in a reset notice - stay
     selectable. */
  button,.tab,.chip,.sheet-row,.mini-cal-day,.mini-cal-month,.mini-cal-day-header,
  .month-day-header,.week-header-cell,.week-hour-label{user-select:none; -webkit-user-select:none}
  select{font-weight:500}
  select{-webkit-appearance:none !important; -moz-appearance:none !important; appearance:none !important;
    padding-right:32px !important;
    background-repeat:no-repeat !important; background-position:right 10px center !important; background-size:12px !important;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23101825' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E") !important;}
  [data-theme="dark"] select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F0F2F5' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E") !important;}
  @media(prefers-color-scheme:dark){
    :root:not([data-theme="light"]) select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F0F2F5' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E") !important;}
  }
  button:hover{border-color:var(--accent); color:var(--accent)}
  button.primary{background:var(--accent); border-color:var(--accent); color:#fff}
  button.primary:hover{color:#fff; opacity:.92}
  /* ANY disabled button, app-wide (e.g. "Add user"/"Create workspace" once a capacity limit is hit,
     or Deactivate/Remove on a workspace with an active subscription - see
     updateAddUserCapacityWarning/updateHostTenantCount/renderWorkspaceRow in admin.js), otherwise
     keeps whatever custom background/border-color it had (accent blue for .primary, danger red for
     .danger, etc.) and looks completely indistinguishable from a working button - browsers don't
     dim a custom color automatically just because the element is disabled. Placed after every
     other button rule above (including .primary/.danger's own colors) so it wins on source order
     despite matching specificity, whichever class the disabled button happens to have. */
  button:disabled{background:var(--line); border-color:var(--line); color:var(--muted); cursor:not-allowed}
  button:disabled:hover{background:var(--line); border-color:var(--line); color:var(--muted)}
  button.danger{border-color:#C0392B; color:#C0392B}

  /* Icon is two overlaid emoji, each clipped to a half - by default (system mode) sun shows on
     the left half and moon on the right half, giving one merged "half sun / half moon" icon.
     Light/dark mode un-clip their own half and hide the other, since only that one icon applies.
     Driven purely by the data-theme-mode attribute (set synchronously pre-paint - see the head
     script) so the icon is correct from the very first frame, with no JS-timing-dependent flash. */
  /* A circle, square width and height, to sit as a pair with the round account monogram beside it. */
  .theme-toggle{position:relative; width:32px; height:32px; padding:0; font-size:16px; background:transparent; border:1px solid var(--line); border-radius:50%; cursor:pointer}
  .theme-toggle:hover{border-color:var(--accent)}
  .theme-toggle .theme-icon{position:absolute; inset:0; display:flex; align-items:center; justify-content:center; pointer-events:none}
  .theme-toggle .theme-icon-sun{clip-path:inset(0 50% 0 0)}
  .theme-toggle .theme-icon-moon{clip-path:inset(0 0 0 50%)}
  html[data-theme-mode="light"] .theme-toggle .theme-icon-sun{clip-path:none}
  html[data-theme-mode="light"] .theme-toggle .theme-icon-moon{display:none}
  html[data-theme-mode="dark"] .theme-toggle .theme-icon-moon{clip-path:none}
  html[data-theme-mode="dark"] .theme-toggle .theme-icon-sun{display:none}

  /* Same circular accent-filled icon button the standalone onboarding-guide pages use for their
     own "Exit to PluraSpace" control (docs/onboarding/*.html) - the one shared definition for
     both, so they can't drift out of sync in size again (those pages used to carry their own
     duplicate 34px copy of this rule; removed in favor of this one, which the 1279px breakpoint
     below still grows to 34px on narrow screens, same as .theme-toggle). */
  .icon-btn{width:32px; height:32px; padding:0; border-radius:50%; flex-shrink:0;
    background:var(--accent); border:1px solid var(--accent); color:#fff;
    display:flex; align-items:center; justify-content:center; cursor:pointer}
  .icon-btn:hover{opacity:.88; color:#fff}
