/* ============================================================
   RALLY V3 SHELL
   Link AFTER cobalt-tokens.css + cobalt-components.css: this file
   is composition only - every color and size reads through the
   cobalt tokens, nothing here restyles the design system.

   THE FROZEN SKELETON: one chrome for every identity. Recognition
   never reflows it. Two gating mechanisms, used deliberately:

   1. RESERVED SLOTS (visibility) - elements that only some
      identities may use keep their box for everyone, so the
      chrome's geometry is identical across roles:
        [data-key] slots (room entries, as-stamps, "your plan" tags)
   2. FIXED-BOX SWAPS (display, inside a fixed-size container) -
        .acct-slot   Sign in <-> avatar, same reserved width
        .room-slot   the labeled room entry, variants stacked in
                     ONE grid cell sized to the widest label

   HARD BUDGET: recognition changes ONLY leaf nodes (prices, labels,
   button faces) and which labeled entry lights inside the reserved
   room slot. Nothing under the topbar may come or go with identity.
   ============================================================ */

/* ---------------- the one shell ---------------- */
.shell{min-height:100dvh; display:flex; flex-direction:column}
body{padding-bottom:calc(66px + env(safe-area-inset-bottom, 0px))} /* room for the demo dock */

/* ---------------- topbar: section pills ---------------- */
.pills{display:flex; align-items:center; gap:2px; min-width:0; max-width:100%;
  overflow-x:auto; scrollbar-width:none}
.pills::-webkit-scrollbar{display:none}
.pills a{display:inline-flex; align-items:center; gap:7px; min-height:40px; padding:0 13px;
  border-radius:var(--r-full); font-size:14px; font-weight:650; color:var(--ink-2);
  white-space:nowrap; transition:.15s; flex:0 0 auto}
.pills a:hover{background:var(--surface-2); color:var(--ink)}
.pills a.on{background:var(--brand-tint); color:var(--brand-ink)}
@media (max-width:760px){
  /* two-row topbar: brand + account stay up, the pills get their own row.
     Identity never changes this - it is pure viewport response. */
  .topbar .pills{order:9; flex-basis:100%}
}

/* ---------------- the room slot (labeled wayfinding, reserved box) ----------------
   ONE slot in the topbar holds every role's labeled way into its room:
   "Members Lounge" for a member, "Staff Area" for desk and owner. The
   variants are stacked in the SAME grid cell, so the slot's box is the
   width of the widest label for EVERY role (guests included) - the bar
   never measures the difference when recognition lights one of them. */
.room-slot{display:grid; flex:0 0 auto}
.room-entry{grid-area:1/1; justify-self:end; display:inline-flex; align-items:center; gap:8px;
  min-height:36px; padding:0 13px; border:1px solid var(--line-strong);
  border-radius:var(--r-full); background:var(--surface); color:var(--ink-2);
  font-size:12.5px; font-weight:700; white-space:nowrap;
  transition:border-color .15s, color .15s, background .15s} /* NOT visibility: the
  role repaint must swap entries instantly, in the same frame as every other leaf */
.room-entry .ic{width:15px; height:15px}
.room-entry:hover{border-color:var(--brand); color:var(--brand-ink)}
.room-entry:focus-visible{outline:none; box-shadow:var(--ring)}
.room-entry .rl-s{display:none}
@media (max-width:640px){
  .room-entry .rl-l{display:none}
  .room-entry .rl-s{display:inline}
  .room-entry{padding:0 11px}
}

/* ---------------- room-link pill (used by the rooms' own topbars) ----------------
   The rooms keep an easy, always-labeled way back: front desk -> home,
   lounge -> front desk for staff. Same family as .room-entry. */
.staff-door{display:inline-flex; align-items:center; gap:8px; min-height:36px; padding:0 13px;
  border:1px dashed var(--line-strong); border-radius:var(--r-full); background:var(--surface);
  color:var(--ink-2); font-size:12.5px; font-weight:700; white-space:nowrap; flex:0 0 auto;
  transition:.15s}
.staff-door .ic{width:15px; height:15px}
.staff-door:hover{border-color:var(--brand); border-style:solid; color:var(--brand-ink)}
.staff-door:focus-visible{outline:none; box-shadow:var(--ring)}
@media (max-width:640px){ .staff-door span{display:none} .staff-door{padding:0 10px} }

/* ---------------- account slot: Sign in <-> avatar ----------------
   A fixed-width slot at the end of the topbar. The repaint swaps its
   content; the topbar never measures the difference. */
.acct-slot{width:88px; flex:0 0 auto; display:flex; justify-content:flex-end; align-items:center}
.signin{display:none}
html[data-role="guest"] .signin{display:inline-flex}
.acct{display:none; border:0; background:transparent; padding:2px; border-radius:50%}
html[data-role="member"] .acct,
html[data-role="desk"] .acct,
html[data-role="owner"] .acct{display:inline-flex}
.acct:focus-visible{outline:none; box-shadow:var(--ring)}

/* very small screens: the mark carries the brand, the words yield.
   Pure viewport response - identity never changes this. */
@media (max-width:420px){
  .topbar{column-gap:8px}
  .topbar .wordmark .wm{display:none}
}

/* ---------------- reserved-slot key gating ----------------
   [data-key="role role ..."] keeps its box for everyone and turns
   visible only for the listed identities. Zero reflow by design. */
[data-key]{visibility:hidden}
html[data-role="guest"]  [data-key~="guest"],
html[data-role="member"] [data-key~="member"],
html[data-role="desk"]   [data-key~="desk"],
html[data-role="owner"]  [data-key~="owner"]{visibility:visible}

/* "acting as" stamp for privileged verbs (Changeover's safety rule) */
.as-stamp{display:inline-flex; align-items:center; gap:5px; padding:3px 9px; border-radius:var(--r-full);
  background:var(--surface-2); border:1px solid var(--line); color:var(--ink-3);
  font-size:10.5px; font-weight:800; letter-spacing:.05em; text-transform:uppercase; white-space:nowrap}
.as-stamp .ic{width:11px; height:11px}

/* ---------------- content frame + footer ---------------- */
.frame{width:100%; max-width:1200px; margin:0 auto;
  padding:clamp(18px,3.5vw,30px) clamp(14px,3.5vw,24px) clamp(48px,8vw,84px)}
.shell-foot{margin-top:auto; border-top:1px solid var(--line)}
.shell-foot .frame{padding-top:20px; padding-bottom:28px; color:var(--ink-3);
  font-size:var(--fs-xs); font-weight:600}

/* ---------------- DEMO: the "View as" dock ----------------
   Mock-only stand-in for real auth. Clearly labelled; never part
   of the product chrome. Same persistence key as V1: concept-role. */
.viewas{position:fixed; left:50%; bottom:12px; transform:translateX(-50%); z-index:90;
  display:flex; align-items:center; gap:4px; padding:7px 9px;
  max-width:calc(100vw - 12px); overflow-x:auto; scrollbar-width:none;
  border:1px solid var(--line-strong); border-radius:var(--r-full);
  background:color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  box-shadow:var(--shadow-3)}
.viewas::-webkit-scrollbar{display:none}
.viewas .vtag{flex:0 0 auto; display:inline-flex; flex-direction:column; line-height:1.15;
  padding:0 8px 0 6px; font-size:9.5px; font-weight:800; letter-spacing:.09em;
  text-transform:uppercase; color:var(--ink-3); white-space:nowrap; border:0}
.viewas .vtag b{color:var(--brand-ink); font-size:10.5px; letter-spacing:.09em}
.viewas button{flex:0 0 auto; display:inline-flex; align-items:center; gap:7px;
  border:0; background:transparent; color:var(--ink-2); font:inherit; font-size:12.5px;
  font-weight:700; padding:5px 12px 5px 6px; border-radius:var(--r-full); cursor:pointer;
  white-space:nowrap; transition:.15s}
.viewas button:hover{background:var(--surface-2); color:var(--ink)}
.viewas button.on{background:var(--brand-tint); color:var(--brand-ink)}
.viewas button:focus-visible{outline:none; box-shadow:var(--ring)}
.viewas button .av{width:22px; height:22px; font-size:9px}
@media (max-width:480px){
  .viewas button{font-size:11.5px; padding:5px 9px 5px 5px; gap:5px}
  .viewas .vtag{padding:0 6px 0 4px}
}

@media (max-width:560px){
  .theme-toggle span{display:none}
  .theme-toggle{padding:0 11px}
}
