/* hive-keeper — shared styles for both the user portal and the admin SPA.
   Loaded before each app's own stylesheet (app.css / admin/app.css), which add
   page-specific rules on top. These custom styles sit on top of Pico. */

:root {
  /* Pico scales rem via the root font-size; 87.5% ≈ 14px base. */
  font-size: 87.5%;
  /* Status colours taken from the logo: navy blue for info/confirmations,
     rose/magenta for errors and warnings. */
  --hk-info: #243d7a;
  --hk-error: #cc1b6b;
  /* Tint form controls (checkboxes, native date/time pickers) with the purple
     accent. The native date-picker popup only honours accent-color in some
     browsers (Chromium yes, Firefox largely ignores it). */
  accent-color: var(--pico-primary);
}

/* Hide Alpine-controlled markup until Alpine has initialised (avoids FOUC). */
[x-cloak] {
  display: none !important;
}

/* ---- Login / activation / reset card ---- */
.login-view {
  max-width: 24rem;
  margin: 12vh auto 0;
}

/* Logo: large on the login card, compact in the top nav. */
.login-logo {
  display: block;
  height: 4.5rem;
  margin: 0 auto 0.75rem;
}

/* Login head (logo + wordmark + subtitle) centred under the logo. */
.login-view hgroup {
  text-align: center;
}

/* Wordmark: "HIVE" bold, "KEEPER" light. */
.wordmark {
  font-weight: 300;
  letter-spacing: 0.05em;
  margin-bottom: 0.25rem;
}

.hive {
  font-weight: 800;
}

/* ---- Top-nav brand ---- */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.brand-logo {
  height: 2.4rem;
}

/* Brand wordmark next to the logo. */
.brand-name {
  font-size: 1.05rem;
  font-weight: 300;
  letter-spacing: 0.04em;
}

/* Clickable brand → home. */
.brand-home {
  cursor: pointer;
}

/* ---- Main navigation ---- */
nav.topnav {
  margin-bottom: 1.5rem;
  border-bottom: 1px solid var(--pico-muted-border-color);
  /* Three groups: brand | links | utility. The brand's auto margin pushes the
     links + utility together on the right (replaces Pico's space-between). */
  justify-content: flex-start;
}

nav.topnav > .nav-brand {
  margin-right: auto;
}

/* Menu links: neutral colour, bold when active. Pico drives link colour through
   --pico-color (flipping to the accent on hover/active), so override the var. */
nav.topnav a {
  --pico-color: var(--pico-contrast);
  --pico-underline: transparent;
}

nav.topnav a[aria-current="page"] {
  font-weight: 700;
}

/* The container now always carries side padding, so we let Pico's negative side
   margins on the first/last nav <ul> stand: they cancel the edge items' padding
   so the logo (left) and user menu (right) sit flush with the page content. */

/* Breadcrumb on sub-pages — sits under the top nav; links stay neutral. */
nav[aria-label="breadcrumb"] {
  margin-top: 0.25rem;
  margin-bottom: 0.5rem;
}

nav[aria-label="breadcrumb"] a {
  --pico-color: var(--pico-contrast);
  --pico-underline: transparent;
}

/* ---- Text helpers ---- */
.muted {
  color: var(--pico-muted-color);
}

.error {
  color: var(--hk-error);
  font-weight: 600;
}

.info {
  color: var(--hk-info);
  font-weight: 600;
}

/* Link-style button (e.g. "Forgot password?") — not a boxed button. */
.link-button {
  display: block;
  width: 100%;
  margin-top: 0.5rem;
  padding: 0.25rem;
  background: none;
  border: none;
  color: var(--pico-primary);
  font-size: 0.85em;
  text-decoration: underline;
  cursor: pointer;
}

.link-button:hover {
  color: var(--pico-primary-hover);
}

/* ---- Toast notifications: stacked top-right, colour-coded, click to dismiss ---- */
.toast-stack {
  position: fixed;
  top: 1.25rem;
  right: 1.25rem;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  width: min(30rem, calc(100vw - 2.5rem));
}

.toast {
  padding: 1rem 1.25rem;
  border-radius: var(--pico-border-radius);
  color: #fff;
  font-size: 1em;
  font-weight: 600;
  line-height: 1.4;
  box-shadow: var(--pico-card-box-shadow);
  cursor: pointer;
  animation: toast-in 0.2s ease-out;
}

/* Info/success toasts follow the accent; text uses the accent's readable inverse. */
.toast.info {
  background: var(--pico-primary-background);
  color: var(--pico-primary-inverse);
}

.toast.error {
  background: var(--hk-error);
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-0.5rem); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---- Avatar menu (top-right): round initial button + dropdown panel ---- */
.avatar-menu {
  position: relative;
  margin: 0;
  list-style: none;
}

button.avatar {
  width: auto;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  --pico-box-shadow: none;
}

button.avatar:focus {
  outline: none;
  box-shadow: none;
}

/* Keep a visible ring only for keyboard focus. */
button.avatar:focus-visible .avatar-circle {
  outline: 2px solid var(--pico-primary);
  outline-offset: 2px;
}

.avatar-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 50%;
  background: var(--pico-primary-background);
  color: var(--pico-primary-inverse);
  font-weight: 700;
}

.avatar-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.4rem);
  z-index: 10;
  min-width: 16rem;
  padding: 0.75rem;
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  box-shadow: var(--pico-card-box-shadow);
}

.avatar-name {
  margin: 0 0 0.1rem;
  font-weight: 600;
}

.avatar-email {
  margin: 0 0 0.5rem;
  font-size: 0.85em;
  color: var(--pico-muted-color);
  word-break: break-all;
}

/* Subtle menu-item look (not a boxed button), distinct from Sign out. Pico
   redefines --pico-color to the button text inside <button>, so use
   --pico-contrast to stay readable on the panel background. */
.avatar-action {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0.4rem 0.5rem;
  background: none;
  border: none;
  border-radius: var(--pico-border-radius);
  text-align: left;
  font-size: 0.9em;
  font-weight: normal;
  color: var(--pico-contrast);
  cursor: pointer;
}

.avatar-action:hover {
  background: var(--pico-secondary-background);
  color: var(--pico-secondary-inverse);
}

.avatar-divider {
  margin: 0.4rem 0;
  border: none;
  border-top: 1px solid var(--pico-muted-border-color);
}

.avatar-signout {
  width: 100%;
  margin: 0;
}

.avatar-section {
  margin: 0.2rem 0.5rem 0.1rem;
  font-size: 0.72em;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pico-muted-color);
}

.tenant-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.tenant-option[aria-current='true'] {
  font-weight: 600;
}

.tenant-check {
  color: var(--pico-primary);
}

/* Role checkbox rows in the invite / edit-roles dialogs. */
.role-check {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.15rem 0;
  font-weight: normal;
}

/* ---- Modal footer: actions on the right, compact ---- */
dialog article footer {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}

dialog article footer button {
  width: auto;
  margin: 0;
}

/* ---- Destructive inline button: red outline (delete actions) ---- */
button.outline.danger {
  --pico-color: var(--pico-del-color, #b3261e);
  --pico-border-color: var(--pico-del-color, #b3261e);
}

button.outline.danger:is(:hover, :focus, :active) {
  --pico-color: var(--pico-del-color, #b3261e);
  --pico-border-color: var(--pico-del-color, #b3261e);
  --pico-background-color: transparent;
}

/* Solid destructive button (delete account). A fixed semantic red — independent
   of the tenant accent — with white text for contrast (Pico would otherwise use
   the dark default text colour on the red fill). */
button.danger:not(.outline) {
  --pico-background-color: #d92d20;
  --pico-border-color: #d92d20;
  --pico-color: #fff;
  color: #fff;
}

button.danger:not(.outline):is(:hover, :focus, :active) {
  --pico-background-color: #b42318;
  --pico-border-color: #b42318;
  --pico-color: #fff;
  color: #fff;
}

/* Danger-zone section + slide-to-confirm switch. Border matches the delete
   button's red. */
.danger-zone {
  border: 1px solid #d92d20;
}

.confirm-switch {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.75rem 0;
}

/* ---- Tenant logo upload preview ---- */
.logo-field .logo-preview {
  max-height: 6rem;
  max-width: 16rem;
  display: block;
  margin-bottom: 0.75rem;
}

/* ---- Modal close "✕" (top-right of any dialog) ---- */
dialog article {
  position: relative;
}
/* The ✕ is absolutely positioned top-right; reserve that space in the dialog
   header so a long title (e.g. the map view's "name — location") wraps before it
   instead of running underneath. */
dialog article > header {
  padding-right: 2.75rem;
}

.dialog-x {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  width: 2rem;
  height: 2rem;
  margin: 0;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  line-height: 1;
  background: transparent;
  border: none;
  color: var(--pico-muted-color);
  cursor: pointer;
  --pico-box-shadow: none;
}
.dialog-x:hover,
.dialog-x:focus-visible {
  color: var(--pico-contrast);
  background: transparent;
}

/* ---- flatpickr: a Close action at the foot of the calendar ---- */
.flatpickr-calendar .fp-close {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0.4rem;
  border: none;
  border-top: 1px solid var(--pico-muted-border-color);
  background: transparent;
  color: var(--pico-primary);
  font-size: 0.85em;
  cursor: pointer;
  --pico-box-shadow: none;
}
.flatpickr-calendar .fp-close:hover {
  background: var(--pico-secondary-background);
}

/* ---- Reading cards: header, collapsible value table, CSV toolbar (shared) ---- */
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.card-head h3 {
  margin: 0;
  /* Grow to fill the row so the action buttons (fullscreen + export) sit together
     on the right, regardless of how many there are. */
  flex: 1;
}
.values-details {
  margin-top: 0.75rem;
}
.values-details > summary {
  cursor: pointer;
  font-size: 0.9em;
  font-weight: 600;
  color: var(--pico-primary);
}
.values-toolbar {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.5rem;
}
.values-toolbar button {
  width: auto;
  margin: 0;
  padding: 0.25rem 0.7rem;
  font-size: 0.85em;
}
.values-table-wrap {
  margin-top: 0.6rem;
  max-height: 22rem;
  overflow: auto;
}
.values-table {
  margin: 0;
  font-size: 0.85em;
}
.values-table th,
.values-table td {
  padding: 0.3rem 0.6rem;
}
.values-table thead th {
  position: sticky;
  top: 0;
  background: var(--pico-card-background-color);
  z-index: 1;
  white-space: nowrap;
}
.values-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.values-table .nowrap {
  white-space: nowrap;
}
/* Min/Max column: kept subtle next to the prominent value. */
.values-table .minmax {
  color: var(--pico-muted-color);
}
/* A header with an explanatory hover (title): show it's interactive. */
.values-table th.hint {
  cursor: help;
  text-decoration: underline dotted;
  text-underline-offset: 0.2rem;
}

/* ---- Per-row "⋮" action menu (shared by admin + portal) ---- */
.kebab-menu {
  position: relative;
  /* inline-block so it flows with the row's action buttons (a block here, or
     display:flex on the cell, would break the table's column layout). */
  display: inline-block;
  vertical-align: middle;
}
.kebab-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.3rem);
  z-index: 10;
  min-width: 9rem;
  /* Grow to fit the longest entry instead of wrapping it. */
  width: max-content;
  max-width: 18rem;
  padding: 0.4rem;
  background: var(--pico-card-background-color);
  border: 1px solid var(--pico-muted-border-color);
  border-radius: var(--pico-border-radius);
  box-shadow: var(--pico-card-box-shadow);
}
.kebab-action {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0.4rem 0.5rem;
  background: none;
  border: none;
  border-radius: var(--pico-border-radius);
  text-align: left;
  white-space: nowrap;
  font-size: 0.9em;
  font-weight: normal;
  color: var(--pico-contrast);
  cursor: pointer;
}
.kebab-action:hover {
  background: var(--pico-secondary-background);
  color: var(--pico-secondary-inverse);
}
/* Delete entry: red text on the panel (a menu item, not a filled button). The
   selector matches `button.danger:not(.outline)`'s specificity and comes later,
   so the global white-on-red danger-button style doesn't make it invisible. */
button.kebab-action.danger,
button.kebab-action.danger:is(:hover, :focus, :active) {
  color: #d92d20;
  background: none;
}
button.kebab-action.danger:is(:hover, :focus, :active) {
  background: var(--pico-secondary-background);
}
.kebab-divider {
  margin: 0.3rem 0;
  border: none;
  border-top: 1px solid var(--pico-muted-border-color);
}

/* ---- flatpickr: tint the calendar with the tenant accent colour ---- */
.flatpickr-day.selected,
.flatpickr-day.selected:hover,
.flatpickr-day.selected:focus,
.flatpickr-day.startRange,
.flatpickr-day.endRange {
  background: var(--pico-primary);
  border-color: var(--pico-primary);
  color: var(--pico-primary-inverse);
}
.flatpickr-day.today {
  border-color: var(--pico-primary);
}
.flatpickr-day.today:hover,
.flatpickr-day.today:focus {
  background: var(--pico-primary);
  border-color: var(--pico-primary);
  color: var(--pico-primary-inverse);
}

/* ---- Accent-colour palette picker (appearance settings) ---- */
.swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0.25rem 0 1rem;
}
.swatch {
  width: 1.9rem;
  height: 1.9rem;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  --pico-box-shadow: none;
}
.swatch.selected {
  outline: 2px solid var(--pico-contrast);
  outline-offset: 2px;
}

/* Modals: pin to the top and size to the *dynamic* viewport height. Pico centres
   dialogs and caps them at 100vh; on mobile the visible area is shorter than
   100vh (address bar), so a tall centred modal had its top — the header — pushed
   off-screen. Top-aligning means any overflow only ever extends downward (and the
   article scrolls internally), keeping the header visible. */
dialog {
  align-items: flex-start;
}

dialog > article {
  margin-top: clamp(1rem, 4vh, 3rem);
  margin-bottom: 1.5rem;
  max-height: calc(100vh - 2 * clamp(1rem, 4vh, 3rem));
  max-height: calc(100dvh - 2 * clamp(1rem, 4vh, 3rem));
}

/* ---------------------------------------------------------------------------
   Responsive — narrow viewports (phones / small tablets). The layout is
   desktop-first (Pico defaults); these rules keep it from overflowing small.
   --------------------------------------------------------------------------- */

/* Wide tables scroll horizontally inside their card instead of stretching the
   whole page (there is no per-table wrapper, so scope to tables in cards). */
@media (max-width: 700px) {
  article table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* Let the top nav wrap to a second line instead of running off-screen. */
@media (max-width: 640px) {
  nav.topnav {
    flex-wrap: wrap;
    row-gap: 0.25rem;
  }

  nav.topnav > ul {
    flex-wrap: wrap;
  }

  /* Two rows on phones: row 1 = brand (left) + language/user menu (right),
     row 2 = the nav links. The links take a full row of their own (flex-basis
     100%) and order after the utility group so they wrap below it. */
  nav.topnav > .nav-links {
    order: 3;
    flex-basis: 100%;
    justify-content: flex-start;
    /* Match the negative margin Pico puts on the first ul so the wrapped menu
       row sits flush-left, aligned with the logo and page content. */
    margin-left: calc(var(--pico-nav-element-spacing-horizontal) * -1);
  }

  /* Pico gives nav items 1rem of vertical padding; once the menu wraps to its
     own row that stacks up into a big gap under the logo. Tighten it on phones. */
  nav.topnav {
    row-gap: 0;
    padding-top: 0.45rem;
  }

  nav.topnav li {
    padding-top: 0.35rem;
    padding-bottom: 0.35rem;
  }

  /* …but give the menu row a bit more breathing room below it. */
  nav.topnav > .nav-links > li {
    padding-bottom: 0.7rem;
  }

  /* The utility group's dropdowns open with right:0; keeping it at the right
     edge (brand's auto margin) means they never spill off-screen. Cap the panel
     width to the viewport as a safety net. */
  .lang-panel,
  .avatar-panel {
    max-width: calc(100vw - 1rem);
  }
}

/* Searchable combobox (e.g. the deployment forage picker): a text input plus a
   filtered, scrollable result list with a capped height so a long list never
   blows up a modal. */
.combo {
  position: relative;
}

.combo-list {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  right: 0;
  margin: 0.15rem 0 0;
  padding: 0.25rem;
  list-style: none;
  max-height: 14rem;          /* ~6–7 rows, then scroll */
  overflow-y: auto;
  background: var(--pico-form-element-background-color, var(--pico-background-color));
  border: 1px solid var(--pico-form-element-border-color, var(--pico-muted-border-color));
  border-radius: var(--pico-border-radius);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}

.combo-opt {
  padding: 0.35rem 0.6rem;
  border-radius: var(--pico-border-radius);
  cursor: pointer;
}

.combo-opt:hover,
.combo-opt.sel {
  background: var(--pico-primary-background, var(--pico-secondary-background));
  color: var(--pico-primary-inverse, inherit);
}

.combo-group {
  padding: 0.4rem 0.6rem 0.15rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--pico-muted-color);
}

.combo-empty {
  padding: 0.4rem 0.6rem;
  color: var(--pico-muted-color);
}
