/* The chrome both documents share: the Awinel bar and the capture-mode switch.

   Top-level switch between the two capture domains: Visits (index.html) and Surveys (survey.html).
   Shared by both documents, which otherwise have no stylesheet in common — index.html loads
   styles.css, survey.html carries its own inline rules. Duplicating ~20 lines across the two is how
   they drifted apart in the first place, so this is one file linked twice and precached in sw.js.

   It is deliberately built from two plain <a> elements with no JavaScript. The two documents run two
   different routers (index toggles .screen sections, survey uses a hash router), and a scripted
   switcher would be one more thing that fails to appear when a module load stalls — the exact failure
   mode of the offline bugs this app has already shipped fixes for. Real anchors work before any
   script runs, and the service worker serves both targets from cache. */

.mode-switch {
  flex: 0 0 auto;
  display: flex;
  gap: 4px;
  padding: 6px;
  background: var(--forward-surface, #fff);
  border-bottom: 1px solid var(--forward-border-subtle, #EDEBE7);
}

/* ── The Awinel bar ────────────────────────────────────────────
   ONE bar, used by both documents.

   It lived in styles.css, which survey.html does not load, so Surveys had no bar at all until v112
   gave it a SECOND implementation named .appbar. Two bars is the drift this file exists to prevent,
   and the 2026-08-09 review asked for them to be the same thing, so the shared rules moved here and
   .appbar is gone. What stayed in styles.css is what only Visits has: .topbar-icon (settings,
   notifications), .topbar-info (the info popover) and the disabled-button rule. */
.topbar {
  flex: 0 0 auto; position: relative;
  background: var(--forward-surface);
  padding: 10px 14px;
  display: flex; align-items: center; gap: 10px;
  min-height: 48px;
  border-bottom: 1px solid var(--forward-border-subtle);
}
/* Title + tiny version subscript stacked; the wrapper takes the flex:1 the h1 used to hold, so per-screen
   centering (h1.centered) and the visit-name chevron are unchanged. Version shows on Home only. */
.title-wrap { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; }
.topbar h1 { margin: 0; font-size: 17px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.title-version { font-family: ui-monospace, SFMono-Regular, monospace; font-size: 9px; line-height: 1; letter-spacing: 0.5px; color: var(--forward-text-tertiary); margin-top: 1px; }
.title-version.hidden { display: none; }
/* On the visit screen the title is centered BETWEEN the back button (left) and the info button (right):
   the h1 keeps flex:1 (so it fills that gap and pushes the info button to the right end) and centers its
   text. The visit name is tappable → details (a subtle chevron hints it). */
.topbar h1.centered { text-align: center; }
.topbar h1.tappable { cursor: pointer; }
.topbar h1.tappable::after { content: "›"; display: inline-block; transform: rotate(90deg); margin-left: 6px; opacity: 0.45; font-weight: 400; }
/* Persistent Awinel brand mark at the top-bar left (static — never toggled, so it can't race the
   async init). The dark-theme variant swaps in via [data-theme]. */
.topbar-logo { flex: 0 0 auto; display: inline-flex; align-items: center; }
.topbar-logo .brand-mark { height: 24px; width: auto; display: block; }
.topbar-logo .brand-mark--dark { display: none; }
[data-theme="dark"] .topbar-logo .brand-mark--light { display: none; }
[data-theme="dark"] .topbar-logo .brand-mark--dark { display: block; }
.topbar button { background: transparent; border: 1px solid var(--forward-border-medium); color: var(--forward-text-primary); padding: 6px 12px; border-radius: 8px; }
.topbar button.primary { background: var(--forward-accent); border-color: var(--forward-accent); color: var(--forward-accent-fg); font-weight: 600; }
.topbar .back { padding: 6px 10px; font-size: 22px; line-height: 1; }

/* The bar is the top-most in-flow element in BOTH documents, so it owns the status-bar inset —
   one rule, one owner, no per-document special case.
   This comment used to claim that index.html's #app "already applies it and this adds nothing".
   It did apply it, and this did add it AGAIN: two insets, so Visits rendered a notch-height gap
   above the bar that Surveys did not have. #app's padding-top is gone; this is now the only
   place the inset is spent. */
.topbar { padding-top: calc(10px + env(safe-area-inset-top, 0px)); }

/* survey.html puts a 52px floor under every button, for gloved taps. A bar control is not a tap
   target of that kind, and a 52px back button makes the bar half again as tall. */
.topbar button { min-height: 0; font: inherit; font-weight: 400; cursor: pointer; }
.topbar .back { font-size: 22px; line-height: 1; }

/* ── The bar's right-hand controls: ⓘ and the account button ──────────────────
   These lived in styles.css, which survey.html does not load, so Surveys had a bar with a title and
   nothing else on it. The 2026-08-10 review asked for one bar — "the same in Visits and Surveys,
   i button with info, account button going to settings" — and a rule that only one of the two
   documents can see cannot produce one bar. So they moved here, with the rest of the bar.
   What stayed behind in styles.css is what only Visits has: the notification bell and its badge,
   and the avatar disc that renderSettingsAvatar paints an operator photo into. Surveys has no
   notifications and no operator profile of its own, so its account button is the plain glyph. */
.topbar-icon {
  flex: 0 0 auto;
  background: transparent;
  border: 1px solid var(--forward-border-medium);
  color: var(--forward-text-primary);
  width: 38px; height: 34px;
  padding: 0;
  border-radius: 8px;
  font-size: 18px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.topbar-icon:active { background: var(--forward-bg-canvas); }
.topbar-icon.hidden { display: none; }
/* In Surveys the account control is an <a>, not a <button>, because settings lives in the other
   document. Both inherit the same box; the anchor must not also inherit a link's underline and
   accent color, which would make it read as a navigation link rather than a bar control. */
a.topbar-icon { text-decoration: none; color: var(--forward-text-primary); }

/* Profile/account button — a rounded square holding a circular avatar disc in Visits, and the bare
   person glyph in Surveys. Same size and position in both, which is the point. */
.profile-btn {
  position: relative;
  width: 36px; height: 36px; border-radius: 8px; padding: 0;
  color: var(--forward-text-secondary);
  font-size: 13px; font-weight: 700;
}

/* Per-screen info affordance — a native <details> so the browser handles open/close (no JS).
   Neutral, informational; never a trust signal. Matches the web InfoButton. */
.topbar-info { flex: 0 0 auto; position: relative; }
.topbar-info.hidden { display: none; }
.info-summary {
  list-style: none;
  cursor: pointer;
  width: 38px; height: 34px;
  border: 1px solid var(--forward-border-medium);
  border-radius: 8px;
  background: transparent;
  color: var(--forward-text-secondary);
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 17px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.info-summary::-webkit-details-marker { display: none; }
.info-summary::marker { content: ""; }
.topbar-info[open] .info-summary { color: var(--forward-text-primary); border-color: var(--forward-text-tertiary); }
.info-panel {
  position: absolute;
  top: 42px; right: 0;
  z-index: 60;
  width: min(300px, 78vw);
  padding: 14px;
  background: var(--forward-surface);
  border: 1px solid var(--forward-border-medium);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  font-size: 14px; line-height: 1.5;
  color: var(--forward-text-secondary);
  text-align: left; white-space: normal; font-weight: 400;
}

/* survey.html has no topbar, so the switch is the topmost element there and owns the safe area.
   In index.html #app already applies it. Unused since survey.html gained the shared .topbar, which
   sits above the switch and owns the inset; kept because a document that links this file without a
   bar still needs it. */
.mode-switch--top { padding-top: calc(6px + env(safe-area-inset-top, 0px)); }


.mode-switch a {
  flex: 1 1 0;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 38px; padding: 0 10px;
  border-radius: 9px;
  font-size: 14px; font-weight: 600;
  text-decoration: none;
  color: var(--forward-text-tertiary, #8A8578);
  background: transparent;
  -webkit-tap-highlight-color: transparent;
}

.mode-switch a:active { transform: scale(0.99); }

/* Hidden below the root screen, in BOTH documents. The 2026-08-10 review asked that the tabs not be
   visible "when viewing a survey", and survey-app.js's render() toggles this class off Boolean(back).
   Visits declined at the time — nothing had asked for it, and the visit log is the screen people
   spend the day on. On 2026-08-19 somebody asked, from inside a visit, which is precisely the screen
   that exemption was protecting; app.js's go() now toggles the same class off `screen !== 'home'`.
   Both documents therefore mean the same thing by it: hidden below the root screen.
   The rule lives in the shared sheet because the class name is the shared vocabulary, and now
   because both documents genuinely use it.

   Two classes deep so it beats `.mode-switch { display: flex }` regardless of which stylesheet a
   document loads last — survey.html declares its own `.hidden` inline, and relying on source order
   across two files is how a rule quietly stops applying. */
.mode-switch.hidden { display: none; }

/* ENTITLEMENT, which is a different thing from the navigation state above.
   `data-modules` is a space-separated list the pre-paint gate stamps on <html> before any stylesheet
   paints, so a workspace with one capture domain never renders the other tab even for a frame — no
   flash, and no JavaScript involved. `data-auth="out"` with no pre-login mode is the login wall,
   where a switcher would only offer a door that is locked.
   Done in CSS on purpose: mode-switch.test.js asserts that app.js never touches this bar and that
   index.html carries no hardcoded `hidden` on it. Both remain true.

   Every selector is qualified with `html[data-modules]` — the attribute must be PRESENT. `[attr~=]`
   never matches an absent attribute, so a bare `:not([data-modules~="visits"])` also matches a
   document the gate never stamped (blocked localStorage, private mode), and BOTH tabs would vanish
   from a perfectly unlocked app with no way to move between the capture domains. That is the same
   mistake, in the other direction, that gateState() avoids with hasAttribute: absence means "no
   gate ran", never "no entitlement". */
html[data-modules]:not([data-modules~="visits"])  .mode-switch a[href$="index.html"],
html[data-modules]:not([data-modules~="surveys"]) .mode-switch a[href$="survey.html"] { display: none; }
/* One domain, or none: the bar itself is noise. Hide the whole thing rather than leave a lone tab
   that navigates to the page you are already on. */
html[data-modules="visits"]  .mode-switch,
html[data-modules="surveys"] .mode-switch,
html[data-modules=""]        .mode-switch { display: none; }

/* The current document. Neutral, not teal — which in this platform means "signature verified" and
   must never be spent on navigation. */
.mode-switch a[aria-current="page"] {
  background: var(--forward-bg-canvas, #F5F3EF);
  color: var(--forward-text-primary, #1F1D1A);
}

/* ENTITLEMENT-CHANGE NOTICE — the message shown when a workspace's modules changed under a signed-in
   device (see refreshEntitlement in awinel-auth-boot.js).

   It lives in this file, rather than in styles.css or a new stylesheet, for one reason: survey.html
   loads tokens.css and this file and nothing else, and the notice must paint in BOTH documents
   because the change that triggers it can move the operator from one to the other. A new stylesheet
   would also mean a new entry in the service worker's ASSETS, and a file that is not precached goes
   stale forever on the first device that loads it.

   The geometry is .update-toast's, deliberately: fixed and OUT OF FLOW, overlaying the bar rather
   than sitting above it. An in-flow banner at the top of the document would become the top-most
   in-flow element and would have to take env(safe-area-inset-top) off the bar, which is the
   double-counted-inset bug v114 was spent fixing. Out of flow, the bar keeps sole ownership. */
.entitlement-notice {
  position: fixed; top: 0; left: 0; right: 0; z-index: 9998;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: calc(env(safe-area-inset-top, 0px) + 12px) 16px 12px;
  background: var(--forward-surface, #fff);
  color: var(--forward-text-primary, #1F1D1A);
  font-size: 14px;
  line-height: 1.4;
  border-bottom: 1px solid var(--forward-border-subtle, #EDEBE7);
  box-shadow: var(--forward-elev-2);
}
.entitlement-notice.hidden { display: none; }
.entitlement-notice span { flex: 1; }
.entitlement-notice button {
  flex: none;
  border: 0;
  background: transparent;
  color: inherit;
  font-size: 16px;
  line-height: 1;
  padding: 4px 8px;
  cursor: pointer;
}
