:root{--bg:#030303;--card:#0b0b0e;--field:#111115;--text:#fff;--soft:#c9c9cf;--muted:#85858e;--gold:#ffc400;--line:rgba(255,255,255,.1);--danger:#ff7c7c;--gold-soft:rgba(255,196,0,.22);--gold-dim:#5a4700;--gold-ink:#171100;--gold-text:#ffd744;--ok:#4ade80;--ok-soft:rgba(74,222,128,.28);--ok-bg:rgba(74,222,128,.05);--ok-text:#9df0bb}
*{box-sizing:border-box}
body{margin:0;min-height:100vh;background:radial-gradient(circle at 50% -5%,rgba(255,190,0,.11),transparent 29rem),var(--bg);color:var(--text);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",Arial,sans-serif}
img{display:block;max-width:100%}

/* The `hidden` attribute has to win, and it does not win on its own.
   A class that sets `display` beats the browser's built-in [hidden]{display:none}
   simply by outranking it: one class selector is more specific than the user
   agent's attribute selector. So

       <div class="inv-actions" id="invActions" hidden>
       .inv-actions{display:flex}

   leaves the element on screen. That is not theoretical: the invitation page
   answered "You accepted this invitation", set el.actions.hidden = true, and
   still showed Decline and Accept -- offering a person the chance to re-answer a
   meeting that was already settled, directly under a message saying it was not.

   !important is the honest way to say the attribute is not negotiable. Without
   it every page has to remember never to set `display` on a class it also hides,
   which is a rule nobody can hold across a growing set of pages, and the failure
   is silent: the attribute reads back as true while the pixels disagree. */
[hidden]{display:none!important}

/* ============================================================== SHARED
   Components that several console pages need. They lived only in individual
   page stylesheets, so any new page had to re-declare them and hardcode the
   palette. They belong here, expressed with the tokens above, so a new page
   only has to style what is genuinely specific to it.
   ======================================================================= */

/* --- form fields -------------------------------------------------------
   These are namespaced with .form- because ".field" is already used by ten
   other pages as a GRID CELL (.fields{display:grid} plus .field.full). A bare
   .field{display:flex} here would override that grid item behaviour and break
   their layout, so the shared form component gets its own class name. */
.form-field{display:flex;flex-direction:column;gap:6px}
.form-field>span{font-size:.78rem;font-weight:700;letter-spacing:.02em}
.form-field small{font-size:.73rem;line-height:1.5;color:var(--muted)}
.form-field code{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:.95em;padding:1px 4px;border-radius:4px;background:rgba(255,255,255,.07)}
.form-field input,.form-field select,.form-field textarea{min-height:40px;padding:9px 12px;border:1px solid rgba(255,255,255,.14);border-radius:9px;background:rgba(0,0,0,.32);color:inherit;font:inherit;font-size:.85rem}
.form-field textarea{min-height:72px;resize:vertical}
.form-field input:focus,.form-field select:focus,.form-field textarea:focus{outline:2px solid var(--gold);outline-offset:1px;border-color:transparent}
.form-field input::placeholder,.form-field textarea::placeholder{color:rgba(255,255,255,.28)}
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:720px){.form-row{grid-template-columns:1fr}}
.section-hint{margin:0;font-size:.8rem;line-height:1.5;color:var(--muted);max-width:70ch}

/* --- buttons ----------------------------------------------------------- */
.btn-primary,.btn-secondary,.btn-danger-ghost{display:inline-flex;align-items:center;justify-content:center;min-height:38px;padding:0 16px;border-radius:9px;font:inherit;font-size:.78rem;font-weight:800;cursor:pointer;text-decoration:none}
.btn-primary{border:1px solid var(--gold);background:var(--gold);color:var(--gold-ink)}
.btn-secondary{border:1px solid var(--gold-dim);background:var(--gold-ink);color:var(--gold)}
.btn-danger-ghost{border:1px solid rgba(255,124,124,.5);background:transparent;color:var(--danger)}
.btn-primary:disabled,.btn-secondary:disabled,.btn-danger-ghost:disabled{opacity:.5;cursor:not-allowed}

/* --- utilities --------------------------------------------------------- */
.mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:.82rem}
.value-copy{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.value-copy strong{word-break:break-all}
.copy-btn,.retry-btn{min-height:28px;padding:0 10px;border:1px solid var(--gold-dim);border-radius:7px;background:var(--gold-ink);color:var(--gold);font:inherit;font-size:.7rem;font-weight:800;cursor:pointer;white-space:nowrap}
.copy-btn:hover,.retry-btn:hover{background:rgba(255,196,0,.16)}
.status-hint{margin:0;font-size:.8rem;line-height:1.5;color:var(--muted);max-width:80ch}

/* --- inline messages --------------------------------------------------- */
.error-box{padding:18px;border:1px solid rgba(255,124,124,.2);border-radius:12px;background:rgba(255,124,124,.04);color:#ffb1b1;font-size:.72rem;line-height:1.6}
.error-box.ok{border-color:var(--ok-soft);background:var(--ok-bg);color:var(--ok-text)}

/* --- status pills ------------------------------------------------------ */
.badge{display:inline-flex;padding:4px 7px;margin:2px;border-radius:999px;border:1px solid var(--line);font-size:.58rem;font-weight:800}
.badge.role{color:var(--gold-text);border-color:var(--gold-soft);background:rgba(255,196,0,.04)}
.badge.enabled{color:#8ce8bc;border-color:rgba(101,221,166,.2);background:rgba(101,221,166,.04)}
.badge.disabled{color:#ff9c9c;border-color:rgba(255,124,124,.2);background:rgba(255,124,124,.04)}
.role-pill{display:inline-flex;padding:7px 10px;border:1px solid var(--gold-soft);border-radius:999px;color:var(--gold-text);background:rgba(255,196,0,.045);font-size:.62rem;font-weight:800}

/* ============================================================== SHELL
   The admin chrome: sticky header, sidebar, welcome row, cards, mobile nav.
   This was duplicated across nine page stylesheets, so a new page had no
   layout at all unless it copied one of them. Taken from users.css verbatim
   so the console looks the same everywhere. Order matters: the mobile nav
   rules must come after the desktop ones so the media query can override.
   ======================================================================= */

.admin-top{position:sticky;top:0;z-index:20;border-bottom:1px solid var(--line);background:rgba(5,5,6,.88);backdrop-filter:blur(18px);width:100%}
.admin-topin{width:100%;height:66px;margin:0;padding:0 24px;display:flex;align-items:center;justify-content:space-between;gap:20px}
.admin-brand{display:flex;align-items:center;gap:11px;text-decoration:none;color:#fff;font-weight:850;letter-spacing:-.02em}
/* canary-logo.png is 1254x1254. Without an explicit box the browser lays it
   out at natural size and it swamps the header and the page content.
   object-fit:contain keeps a non-square replacement from being distorted. */
.admin-brand img{width:35px;height:35px;object-fit:contain;flex:0 0 auto}
.admin-brand small{display:block;color:var(--muted);font-size:.58rem;font-weight:650;letter-spacing:.08em;text-transform:uppercase}
.avatar{width:36px;height:36px;display:grid;place-items:center;border:1px solid rgba(255,205,45,.28);border-radius:50%;background:rgba(255,196,0,.07);color:var(--gold-text);font-size:.72rem;font-weight:900}

.shell{width:100%;margin:0;padding:24px;display:grid;grid-template-columns:210px minmax(0,1fr);gap:24px;align-items:start}
.side{position:sticky;top:86px;height:max-content}
.nav{display:grid;gap:7px}
.nav a{display:flex;align-items:center;gap:10px;padding:11px 13px;border-radius:10px;color:var(--soft);text-decoration:none;font-size:.78rem;font-weight:720}
.nav a:hover,.nav a.active{background:rgba(255,196,0,.07);color:var(--gold-text)}
.nav i{font-style:normal;width:18px;text-align:center}
.logout{margin-top:22px;padding-top:18px;border-top:1px solid var(--line)}

.welcome{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;margin-bottom:24px}
.eyebrow{color:var(--gold-text);font-size:.68rem;font-weight:900;letter-spacing:.16em;text-transform:uppercase}
.panel{border:1px solid var(--line);border-radius:20px;background:linear-gradient(145deg,rgba(255,195,0,.035),rgba(255,255,255,.018)),var(--card);padding:24px}

.mobile-nav{display:none}

@media(max-width:850px){
  .shell{grid-template-columns:1fr;padding-top:24px}
  .side{display:none}
  .mobile-nav{display:grid;position:fixed;left:0;right:0;bottom:0;z-index:30;grid-template-columns:repeat(5,1fr);padding:8px max(8px,env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) max(8px,env(safe-area-inset-left));border-top:1px solid var(--line);background:rgba(7,7,8,.96);backdrop-filter:blur(18px)}
  .mobile-nav a{display:flex;flex-direction:column;align-items:center;gap:3px;padding:6px 2px;color:var(--soft);text-decoration:none;font-size:.56rem;font-weight:720}
  .mobile-nav a span{font-size:1rem;line-height:1}
  .mobile-nav a.active{color:var(--gold-text)}
  main{padding-bottom:78px}
}

/* ============================================================================
   THE HEADER

   The one component every console page has, and the one that had been
   re-declared per page. `.top` was defined in at least two stylesheets with
   different values -- 66px sticky with a blur in the dashboard's, 60px flex with
   padding in MAIL's -- so the same <header class="top"> rendered differently
   depending on which page loaded it, and nothing in the markup said so.

   Moved here for the reason this file exists: a component several pages need
   belongs in one place, expressed with the tokens above, so a new page styles
   only what is genuinely its own.

   Safe to override, deliberately. This loads BEFORE every page stylesheet, so a
   page that declares its own `.top` still wins on order at equal specificity.
   That is what stops this from being a breaking change: adopting the header
   everywhere becomes a matter of deleting a page's copy, not of deleting its
   layout.

   `.avatar` is the profile tile: a rounded square, not a circle. A circle
   crops a square photograph to its inscribed circle, which throws away the
   corners -- and on a group photograph those are usually other people.
   ========================================================================== */
.top{position:sticky;top:0;z-index:20;border-bottom:1px solid var(--line);background:rgba(5,5,6,.88);backdrop-filter:blur(18px)}
.topin{width:min(calc(100% - 32px),1180px);height:66px;margin:auto;display:flex;align-items:center;justify-content:space-between;gap:20px}
.brand{display:flex;align-items:center;gap:11px;color:#fff;text-decoration:none;font-weight:850}
.brand img{width:35px;height:35px;object-fit:contain}
.brand small{display:block;color:var(--muted);font-size:.58rem;font-weight:650;letter-spacing:.08em;text-transform:uppercase}
.userline{display:flex;align-items:center;gap:11px}
.who{text-align:right}
.who strong{display:block;font-size:.76rem}
.who span{display:block;color:var(--muted);font-size:.62rem;margin-top:2px}
/* The profile tile. Width/height and font are declared here rather than left to
   a page so a picture and a pair of initials occupy exactly the same box. */
.avatar{width:36px;height:36px;display:grid;place-items:center;border:1px solid rgba(255,205,45,.28);border-radius:11px;background:rgba(255,196,0,.07);color:var(--gold-text);font-size:.72rem;font-weight:900;position:relative;overflow:hidden}
/* A picture in the tile. Absolutely positioned rather than sized at 100%,
   because .avatar is display:grid with place-items:center, and a percentage
   sized child inside one of those measures zero: place-items makes the item
   size to its content, and an <img> with nothing decoded has none. */
.avatar img.avatar-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}

.with-side-brand{min-height:calc(100vh - 110px);display:flex;flex-direction:column}.side-brand{display:flex;align-items:center;gap:11px;margin-top:auto;padding:18px 12px 12px;border-top:1px solid var(--line);color:var(--muted);text-decoration:none}.side-brand img{width:42px;height:42px;object-fit:contain;flex:none}.side-brand span{display:grid;gap:2px}.side-brand small{font-size:.58rem;line-height:1.2}.side-brand strong{color:var(--soft);font-size:.67rem;line-height:1.25}.side-brand:hover strong{color:var(--gold-text)}@media(max-width:800px){.with-side-brand{min-height:0}.side-brand{margin-top:16px}}

.brand.theme-brand-cswg,.brand.theme-brand-spartannash{display:none}.brand.theme-brand-cswg img{width:min(190px,24vw);height:42px;object-fit:contain}.brand.theme-brand-spartannash img{width:min(300px,34vw);height:62px;object-fit:contain}.brand.theme-brand-cswg span,.brand.theme-brand-spartannash span{display:none}html[data-workspace-theme='cswg-custom'] .top .brand.theme-brand-default,html[data-workspace-theme='spartannash-custom'] .top .brand.theme-brand-default{display:none}html[data-workspace-theme='cswg-custom'] .top .brand.theme-brand-cswg,html[data-workspace-theme='spartannash-custom'] .top .brand.theme-brand-spartannash{display:flex}@media(max-width:560px){.brand.theme-brand-cswg img{width:min(140px,36vw);height:34px}.brand.theme-brand-spartannash img{width:min(220px,50vw);height:50px}}
