/**
 * Reset, typography, layout and accessibility utilities.
 */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: 1.55;
  color: var(--text);
  background: var(--page);
}

h1, h2, h3, h4 {
  margin: 0 0 var(--sp-3);
  line-height: 1.25;
  font-weight: 650;
  text-wrap: balance;
}

h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }

p { margin: 0 0 var(--sp-4); max-width: var(--measure); }

a {
  color: var(--brand-700);
  text-underline-offset: 0.2em;
}
a:hover { color: var(--brand-600); }

img { max-width: 100%; height: auto; }

/* ---------------------------------------------------------------------------
   Focus. A visible focus indicator is non-negotiable: the whole app must be
   operable by keyboard alone, and :focus-visible keeps it off mouse clicks.
   --------------------------------------------------------------------------- */

:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

/* Only remove the default ring where a replacement is provided above. */
:focus:not(:focus-visible) { outline: none; }

/* ---------------------------------------------------------------------------
   Accessibility utilities
   --------------------------------------------------------------------------- */

/** Available to screen readers, invisible on screen. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/** Skip link: hidden until focused, then pinned to the top of the viewport. */
.skip-link {
  position: absolute;
  left: var(--sp-3);
  top: -4rem;
  z-index: 100;
  padding: var(--sp-2) var(--sp-4);
  background: var(--surface-raised);
  color: var(--text);
  border: 2px solid var(--brand-600);
  border-radius: var(--radius);
  font-weight: 600;
  transition: top 120ms ease-in;
}
.skip-link:focus { top: var(--sp-3); }

/* ---------------------------------------------------------------------------
   App shell
   --------------------------------------------------------------------------- */

.app-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4);
  min-height: var(--header-height);
  padding: var(--sp-2) var(--sp-5);
  background: var(--brand-800);
  color: var(--text-inverse);
  box-shadow: var(--shadow-sm);
}

.app-header a { color: var(--text-inverse); }

.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  white-space: nowrap;
}

/*
 * The app icon itself, so the mark in the header and the icon on a home screen
 * are the same thing. The artwork carries its own rounded tile and padding -
 * nothing is painted behind it, and clipping it again here would shave the
 * corners it already has.
 */
.brand-mark {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
  flex: none;
}

.app-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin-inline-start: auto;
}

.app-nav a {
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 550;
  text-decoration: none;
}

.app-nav a:hover { background: rgb(255 255 255 / 0.14); }

/* The current page is marked with aria-current, so the styling follows the
   semantics rather than a separate class. */
.app-nav a[aria-current="page"] {
  background: rgb(255 255 255 / 0.2);
  box-shadow: inset 0 -2px 0 var(--text-inverse);
}

/* ---------------------------------------------------------------- */
/* Account avatar and its menu                                        */
/* ---------------------------------------------------------------- */

.account { position: relative; display: flex; align-items: center; }

.avatar {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  border: 2px solid rgb(255 255 255 / 0.5);
  background: rgb(255 255 255 / 0.16);
  color: var(--text-inverse);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .02em;
  display: grid;
  place-items: center;
  cursor: pointer;
  padding: 0;
}

.avatar:hover { background: rgb(255 255 255 / 0.28); }

.account-menu {
  position: absolute;
  top: calc(100% + var(--sp-2));
  inset-inline-end: 0;
  z-index: 60;
  min-width: 17rem;
  padding: var(--sp-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  text-align: start;
}

/* Label above value, so a long email or role list never squeezes the label. */
.account-facts { margin: 0 0 var(--sp-3); display: grid; gap: var(--sp-1); }
.account-facts dt {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.account-facts dd {
  margin: 0 0 var(--sp-2);
  font-size: var(--text-sm);
  word-break: break-word;
}

.account-dev {
  margin: 0 0 var(--sp-3);
  padding: var(--sp-2);
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger-text);
  font-size: var(--text-xs);
}

/* Square the join where the persona switcher sits directly beneath. */
.account-dev:has(+ .account-dev-personas) {
  margin-bottom: 0;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

/*
  The persona switcher, shown only under the development sign-in bypass. It
  sits inside the same warning-coloured region as the bypass notice above it,
  so it reads as part of that warning rather than as an ordinary setting
  somebody might expect to find in a deployed environment.
*/
.account-dev-personas {
  margin: calc(var(--sp-3) * -1) 0 var(--sp-3);
  padding: var(--sp-2);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger-text);
}

.account-dev-personas select {
  width: 100%;
  margin-top: var(--sp-1);
}

/*
  The admin section of the account menu. Rules above and below set it apart
  from the identity facts above and the sign-out below, so the menu reads as
  three distinct things rather than one long list.
*/
.account-admin {
  margin: 0 calc(var(--sp-3) * -1) var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-block: 1px solid var(--border);
}

.account-admin-label {
  margin: 0 0 var(--sp-1);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .04em;
}

.account-link {
  display: block;
  padding: var(--sp-2);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: var(--text-sm);
  text-decoration: none;
}

.account-link:hover { background: var(--surface-sunken); }

.account-link[aria-current="page"] { font-weight: 700; }

.account-signout {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--danger-border);
  border-radius: var(--radius-sm);
  background: var(--danger-bg);
  color: var(--danger-text);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.account-signout:hover { background: var(--danger-border); color: #fff; }

main {
  padding: var(--sp-5);
  max-width: 1500px;
  margin: 0 auto;
}

.page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}

.page-header p { margin: 0; color: var(--text-muted); }

/* ---------------------------------------------------------------------------
   Date navigator: previous / the date itself / next / today.
   --------------------------------------------------------------------------- */

/* View switcher, then the date pill, then refresh - the mockup's three groups. */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}

/*
 * Previous / the date / next / Today as one pill.
 *
 * The buttons keep their own hit areas but share a single outline, so the four
 * read as one control rather than four that happen to sit together.
 */
.date-group {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

.date-group .btn,
.date-group .date-current {
  border: 0;
  border-radius: 0;
  background: none;
}

/*
 * Hairlines between the segments, never before the first one.
 *
 * The selector has to carry the same weight as the `border: 0` above, or that
 * rule wins and only .date-pick - the one child that is not a .btn - keeps a
 * divider. A bare `> * + *` is one class lighter and lost silently.
 */
.date-group > .btn + *,
.date-group > .date-pick + * { border-inline-start: 1px solid var(--border); }

.date-group .btn:hover,
.date-group .date-current:hover { background: var(--surface-sunken); }

.date-pick { position: relative; display: inline-flex; }

/* Reads as the page heading, behaves as a button. */
.date-current {
  min-height: 2.75rem;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: none;
  color: var(--text);
  font: inherit;
  font-size: var(--text-xl);
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
}

.date-current:hover {
  background: var(--surface-sunken);
  border-color: var(--border-strong);
}

/*
 * Invisible and inert while the button does the talking. Focus is the fallback
 * path: a browser without showPicker() leaves the field focused, and these
 * rules turn it into an ordinary visible date input sitting over the button.
 */
.date-pick input[type="date"] {
  position: absolute;
  inset: 0;
  width: 100%;
  padding: 0 var(--sp-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  opacity: 0;
  pointer-events: none;
}

.date-pick input[type="date"]:focus {
  opacity: 1;
  pointer-events: auto;
}

.app-footer {
  padding: var(--sp-5);
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: var(--text-sm);
  text-align: center;
}

/* ---------------------------------------------------------------------------
   Layout helpers
   --------------------------------------------------------------------------- */

/*
 * `hidden` has to win over any display a component sets for itself.
 *
 * The UA rule is [hidden]{display:none} at zero specificity, so a single class
 * like .segmented{display:flex} silently outranks it - the element vanishes to
 * zero height but still collects its stack margin, leaving a gap with nothing
 * in it. That is what pushed the grid away from the legend above it.
 */
[hidden] { display: none !important; }

.stack > * + * { margin-top: var(--sp-4); }

/*
 * The legend and the hours toggle label the table under them, so they sit
 * close to it - the stack's usual gap makes them read as a band floating
 * between the toolbar and the grid rather than as the grid's own heading.
 */
.stack > .room-tabs,
.stack > .grid-wrap { margin-top: var(--sp-2); }
.stack-sm > * + * { margin-top: var(--sp-2); }

.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}

.spread { justify-content: space-between; }
.grow { flex: 1 1 auto; }

.grid-2 {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
}

.muted { color: var(--text-muted); }
.small { font-size: var(--text-sm); }
.nowrap { white-space: nowrap; }
.text-right { text-align: right; }

/** Wide content scrolls inside its own container; the page never scrolls sideways. */
.scroll-x {
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

/*
 * The phone breakpoint. Also in components.css for the schedule grid - see the
 * note in tokens.css for why the number is written out rather than tokenised.
 *
 * The theme here is vertical budget: the header is sticky, so every row it
 * wraps to is a row the schedule below it never gets back.
 */
@media (max-width: 640px) {
  main { padding: var(--sp-4) var(--sp-3); }
  .app-header { padding: var(--sp-2) var(--sp-3); }

  /*
   * One scrolling row rather than wrapped ones. Even the three links a
   * reviewer sees can wrap inside a sticky header on a narrow phone.
   * The same trade .room-tabs already makes in components.css.
   */
  .app-nav {
    width: 100%;
    margin-inline-start: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
  }

  .app-nav a { white-space: nowrap; }

  .page-header { margin-bottom: var(--sp-3); }
  .toolbar { gap: var(--sp-2); }
}

@media print {
  .app-header, .app-nav, .app-footer, .no-print { display: none !important; }
  /* The screen gets the date as its heading; paper needs the title back. */
  .print-title {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    clip-path: none;
  }
  body { background: #fff; color: #000; }
}
