/* canh backend-only application styles. The canonical design-system regions
 * are generated in shared.css and load before this file. */

/* ---- form fields ------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: 8px; }
.field__label { font-family: var(--font-ui); font-weight: 600; font-size: 13px; color: var(--ink); }
.input {
  font-family: var(--font-mono);
  font-size: 13.5px;
  color: var(--ink);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--r-btn);
  padding: 11px 15px;
  outline: none;
}
.input:focus { border-color: var(--gold); box-shadow: 0 0 0 1.5px var(--gold); }

/* ---- account menu ------------------------------------------------------ */
.account-menu { position: relative; width: max-content; }
.account-menu__trigger {
  display: flex;
  align-items: center;
  gap: 9px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px 4px;
}
.avatar {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--ink-inverse);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-ui);
  font-weight: 800;
  font-size: 14px;
}
.account-menu__caret { color: var(--ink); display: inline-block; transition: transform 0.18s; }
.account-menu__trigger[aria-expanded="true"] .account-menu__caret { transform: rotate(180deg); }
.menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 12px);
  min-width: 200px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-dropdown);
  padding: 7px;
  z-index: 200;
  transition: opacity 0.16s, transform 0.16s, visibility 0.16s;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
}
.menu-panel[data-open="true"] { opacity: 1; visibility: visible; transform: translateY(0); }
.menu-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink);
  padding: 10px 12px;
  border-radius: var(--r-btn);
  cursor: pointer;
}
.menu-item:hover { background: var(--gold); }
.menu-item[aria-current="page"] { background: var(--divider); cursor: default; }
.menu-divider { height: 1px; background: var(--sand); margin: 5px 8px; }
.account-identity { padding: 8px 12px 6px; }
.account-identity__name { display: block; font-family: var(--font-ui); font-weight: 600; font-size: 13px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* No stored name yet → collapse the line so only the email shows. */
.account-identity__name:empty { display: none; }
.account-identity__email { display: block; font-family: var(--font-ui); font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- OAuth permission rows (consent) ----------------------------------- */
.oauth-permission {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 20px 18px;
}
.oauth-permission__icon {
  flex: none;
  width: 34px;
  height: 34px;
  border-radius: var(--r-btn);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  margin-top: 1px;
}
.oauth-permission__icon i { font-size: 19px; }
.oauth-permission__text { flex: 1; min-width: 0; text-align: left; }
.oauth-permission__title { display: block; font-family: var(--font-ui); font-weight: 700; font-size: 14.5px; color: var(--ink); }
.oauth-permission__desc { display: block; font-size: 12.5px; color: var(--muted); line-height: 1.5; margin-top: 2px; }
.oauth-permission__tag {
  flex: none;
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--sand);
  border-radius: var(--r-btn);
  padding: 5px 8px;
  margin-top: 3px;
}
/* toggleable optional scope is a button */
.oauth-permission--toggle { width: 100%; cursor: pointer; font-family: var(--font-ui); transition: background 0.14s, opacity 0.14s; }
.oauth-permission--toggle[aria-pressed="false"] { background: #efe9db; opacity: 0.62; }
.toggle {
  flex: none;
  width: 38px;
  height: 22px;
  border-radius: var(--r-pill);
  background: var(--toggle-off);
  position: relative;
  transition: background 0.16s;
  margin-top: 4px;
}
.oauth-permission--toggle[aria-pressed="true"] .toggle { background: var(--accent); }
.toggle__knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: left 0.16s;
}
.oauth-permission--toggle[aria-pressed="true"] .toggle__knob { left: 18px; }

/* "signed in as" row */
.signed-as {
  display: flex;
  align-items: center;
  gap: 12px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 16px 18px;
}
.signed-as .avatar { width: 34px; height: 34px; font-size: 15px; }
.signed-as__identity { flex: 1; min-width: 0; }
.signed-as__eyebrow { display: block; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted); }
.signed-as__name { display: block; font-family: var(--font-ui); font-weight: 600; font-size: 13.5px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* No stored name yet → the email carries the bold identity line alone. */
.signed-as__name:empty { display: none; }
.signed-as__name:empty + .signed-as__email { font-weight: 600; font-size: 13.5px; color: var(--ink); }
.signed-as__email { display: block; font-family: var(--font-ui); font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- auth (sign-in) card states ---------------------------------------- */
.auth-card { width: 100%; max-width: 540px; min-height: 420px; text-align: center; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.auth-state { display: none; width: 100%; animation: canh-fade 0.28s ease both; }
.auth-card[data-auth-view="welcome"] [data-state="welcome"],
.auth-card[data-auth-view="signing"] [data-state="signing"],
.auth-card[data-auth-view="error"] [data-state="error"] { display: block; }
.spinner {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 3px solid #ece4d2;
  border-top-color: var(--accent);
  margin: 0 auto;
  animation: canh-spin 0.8s linear infinite;
}
.error-chip {
  width: 42px;
  height: 42px;
  border-radius: var(--r-btn);
  background: var(--tint-red);
  color: var(--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto;
  font-family: var(--font-ui);
  font-weight: 800;
  font-size: 24px;
  line-height: 1;
}
@keyframes canh-spin { to { transform: rotate(360deg); } }
@keyframes canh-fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* google "G" button glyph */
.g-glyph { width: 22px; height: 22px; background: #fff; border-radius: 3px; padding: 2px; }

/* ---- auth-gate loading skeleton (templates/_loading.html) ---------------
   Shimmering placeholder bars mirroring the .page layout (eyebrow → h1 →
   lede → card), shown while auth.js resolves the Firebase auth state. Under
   prefers-reduced-motion the global rule below freezes the shimmer to a
   static tint. */
.skeleton__bar {
  height: 14px;
  max-width: 520px;
  border-radius: var(--r-btn);
  /* highlight sits between --divider and --bg (off-token on purpose: shimmer only) */
  background: linear-gradient(100deg, var(--divider) 35%, #f2eee0 50%, var(--divider) 65%);
  background-size: 220% 100%;
  /* rest on the shimmer's from-frame — past the 65% stop the gradient is solid
     --divider, so the reduced-motion static frame is a solid bar, not a fade */
  background-position: 120% 0;
  animation: canh-shimmer 1.6s linear infinite;
}
.skeleton__bar--eyebrow { width: 120px; height: 12px; }
.skeleton__bar--title { width: min(60%, 380px); height: clamp(34px, 5vw, 60px); margin-top: 20px; }
.skeleton__bar--lede { margin-top: 18px; }
.skeleton__bar--lede + .skeleton__bar--lede { margin-top: 10px; }
.skeleton__bar--short { max-width: 380px; }
.skeleton__bar--label { width: 140px; height: 11px; }
.skeleton__card { margin-top: clamp(36px, 5vh, 56px); }
.skeleton__card .skeleton__bar + .skeleton__bar { margin-top: 14px; }
.skeleton__card .skeleton__bar--label { margin-bottom: 22px; }
/* hub variant: centered header + the three-card launcher grid */
.skeleton--hub .skeleton__bar { margin-left: auto; margin-right: auto; }
.skeleton--hub .skeleton__card { margin-top: 0; }
@keyframes canh-shimmer { from { background-position: 120% 0; } to { background-position: -120% 0; } }

/* ---- data table (FR-65: one standard table for every roster — keys, team
   members, pending invitations, invitations; formerly the keys table) --------- */
.data-table { width: 100%; border-collapse: collapse; min-width: 520px; table-layout: fixed; }
.data-table th {
  text-align: left;
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: 13px;
  color: var(--ink);
  padding: 0 16px 12px 16px;
}
.data-table thead tr { border-bottom: 1.5px solid var(--ink); }
.data-table td {
  padding: 16px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.data-table tbody tr:nth-of-type(even) td { background: var(--bg); }
.data-table tbody td:first-child { border-top-left-radius: 8px; border-bottom-left-radius: 8px; }
.data-table tbody td:last-child { border-top-right-radius: 8px; border-bottom-right-radius: 8px; }
/* Right-align only real actions cells (the kebab column) — a data column that
   happens to be last (Role, Joined) must stay left-aligned under its header. */
.data-table tbody td:has(.data-table__actions) { text-align: right; }
.data-table__actions { display: inline-flex; gap: 8px; opacity: 0; transition: opacity 0.14s ease; }
.data-table tbody tr:hover .data-table__actions,
.data-table tbody tr:focus-within .data-table__actions { opacity: 1; }
.table-scroll { overflow-x: auto; }
.empty-state {
  border: 1.5px dashed var(--border);
  border-radius: var(--r-card);
  padding: 44px 24px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.section-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 16px;
}

.error { color: var(--accent); font-size: 13.5px; margin-top: 14px; }

/* Field-level validation: a full-width line under the form's input row (its
   own wrapped flex line), so the message sits directly below the field the
   user must fix rather than at the bottom of the page. */
.field-error {
  flex-basis: 100%;
  color: var(--accent);
  font-size: 13.5px;
  margin-top: -2px;
}

/* ---- teams page --------------------------------------------------------- */
.team-card__head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 8px;
}
.team-card__head h2 { font-size: 20px; }
.team-card__badge {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* solid ink chip with gold text (FR-65) */
  color: var(--gold);
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  padding: 2px 10px;
}
.team-card__invitation { margin: 18px 0 0; }
.team-card__placement { margin: 18px 0 0; }
/* Whitespace spacer that splits the owner card into two zones: the
   invitation-by-email action above, the roster (tabs + table) below — so they
   don't read as one run of controls. No rule, just breathing room; only
   present where an invitation form sits above (owner view). */
.team-card__divider { height: 1px; margin: 24px 0 22px; }

/* in-card roster tabs (FR-65): a segmented control reusing the account-menu
   state semantics — gold fill = hover (clickable), divider fill = selected */
.card-tabs {
  display: inline-flex;
  margin: 20px 0 18px;
  border: 1px solid var(--border); /* matches .menu-panel */
  border-radius: var(--r-btn);
  overflow: hidden; /* clips the tab fills to the rounded corners */
}
.card-tab {
  appearance: none;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink);
  padding: 10px 12px;
}
.card-tab + .card-tab { border-left: 1px solid var(--border); }
.card-tab:hover { background: var(--gold); }
.card-tab[aria-selected="true"] { background: var(--divider); cursor: default; }

/* the card's one destructive action, bottom right (FR-65); the top margin
   mirrors .card's padding so the button sits evenly between the roster and
   the card edge */
.card__footer {
  display: flex;
  justify-content: flex-end;
  margin-top: clamp(30px, 3.4vw, 44px);
}
/* unsquish: .btn--sm's fixed 88px is too tight for "Dissolve team" */
.card__footer .btn--sm { width: auto; padding: 8px 16px; }
/* a footer can also carry a hint line opposite its action (frozen teams) */
.card__footer--split { justify-content: space-between; align-items: center; gap: 16px; }
.card__footer-hint { color: var(--muted); font-size: 13px; }

/* ---- organizations (FR-78): the context chip, the seat combobox, the
   row-action kebab, and two team-card badge variants ---------------------- */
.nav__context {
  /* the active-context indicator, shown ONLY on context-scoped pages (the
     hub, /teams, the org page) — its absence marks a page as person-scoped */
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--divider);
  border-radius: 999px;
  padding: 3px 12px;
  margin-left: 14px;
  margin-right: auto; /* clusters with the wordmark on the left */
  white-space: nowrap;
}
/* the add-to-team combobox: type-ahead over the org's seat list. The
   suggestion panel borrows the account-menu look (surface-alt, gold hover);
   it floats below the input so the card doesn't reflow. */
.combo { position: relative; }
.combo__list {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 50;
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--r-btn);
  box-shadow: var(--shadow-dropdown);
  overflow: hidden;
}
.combo__item {
  appearance: none;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 13px;
  padding: 10px 12px;
  color: var(--ink);
}
.combo__item:hover { background: var(--gold); }
/* the keyboard-active option (aria-activedescendant) matches :hover */
.combo__item--active { background: var(--gold); }
.combo__item + .combo__item { border-top: 1px solid var(--divider); }
.combo__item .combo__meta { color: var(--muted); }
/* the consolidated invitation form's dropdowns (FR-70): organization-role select + team
   multi-select. The floating panel is the account-menu component wholesale
   (.menu-panel/.menu-item — like the row-menu kebab), anchored under an
   .input-styled trigger. */
.select { position: relative; }
.select__btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  cursor: pointer;
  text-align: left;
}
.select__caret { margin-left: auto; color: var(--ink); font-size: 14px; transition: transform 0.18s; }
.select__btn[aria-expanded="true"] .select__caret { transform: rotate(180deg); }
.select .menu-panel {
  right: auto;
  left: 0;
  top: calc(100% + 6px);
  min-width: 100%;
  max-height: 264px;
  overflow-y: auto;
}
.select .menu-item { white-space: nowrap; }
/* selection reads exactly like the account menu's current page */
.select .menu-item[aria-selected="true"] { background: var(--divider); }
/* the keyboard-active option (aria-activedescendant) matches :hover —
   after the selected rule, so gold wins on the active row either way */
.select .menu-item.is-active { background: var(--gold); }
.select__empty { padding: 10px 12px; font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); }
/* the multi-select trigger: an .input-styled box holding chips + the inline
   search field (clicking anywhere in it focuses the search). */
.select__box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  cursor: text;
  padding: 7px 15px;
  min-height: 40px; /* the rendered .input height, so the row doesn't jump */
}
.select__box:focus-within { border-color: var(--gold); box-shadow: 0 0 0 1.5px var(--gold); }
.select__search {
  flex: 1;
  min-width: 70px;
  border: none;
  outline: none;
  background: none;
  font: inherit;
  line-height: normal; /* inputs don't inherit the body line box — match .input */
  color: inherit;
  padding: 0;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--sand);
  border: 1px solid var(--border);
  border-radius: var(--r-btn);
  /* 1px vertical: chip + box padding + border stays within the 40px box */
  padding: 1px 4px 1px 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink);
  white-space: nowrap;
}
.chip__x {
  appearance: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0 4px;
  border-radius: var(--r-btn);
  color: var(--muted);
  font-size: 14px;
  line-height: 1.2;
}
.chip__x:hover { color: var(--ink); background: var(--gold); }
/* row-action kebab (FR-65): the row's actions collapse into a three-dot
   trigger (revealed on row hover like every row action); the dropdown reuses
   the account-menu component wholesale. */
.row-menu { position: relative; display: inline-flex; }
.row-menu__btn {
  appearance: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: var(--r-btn);
  color: var(--ink);
  font-size: 18px;
  line-height: 1;
}
.row-menu__btn:hover { background: var(--divider); }
/* the open dropdown is PORTALED to <body> (row-menu.js positions it from the
   trigger's rect), so neither the td ellipsis rule nor the .table-scroll
   container can clip it — and .table-scroll keeps its overflow-x on narrow
   screens. right:auto neutralizes .menu-panel's right-edge anchoring; the
   panel's top/left are set inline on open. */
.row-menu__panel { position: absolute; right: auto; z-index: 200; }
/* keep the actions cell visible while its menu is open (the pointer leaves
   the row for the portaled dropdown) */
.data-table__actions:has(.row-menu__btn[aria-expanded="true"]) { opacity: 1; }
.team-card__badge--org {
  /* org-context chip: quiet, informational (an org name is data, never a
     trust signal — NFR-5) */
  color: var(--ink);
  background: var(--divider);
  border-color: var(--divider);
}
.team-card__badge--frozen {
  /* dissolve-window state: caution palette, matches .callout tones */
  color: var(--caution-label);
  background: var(--caution-surface);
  border-color: var(--caution-border);
}

/* ---- responsive -------------------------------------------------------- */
@media (max-width: 760px) {
  .data-table [data-lastused] { display: none !important; }
}
@media (max-width: 680px) {
  .choice-grid { grid-template-columns: 1fr; }
}

/* ---- dialog (themed confirm / type-to-confirm, dialog.js) --------------- */
/* A native <dialog> styled as a compact site card; the danger variant
   carries the callout--danger heading idiom (ph-warning + accent). */
.dialog {
  width: min(440px, calc(100vw - 48px));
  background: #fff;
  color: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-dropdown);
  padding: 26px 28px 24px;
  margin: auto; /* keep centered even where UA dialog styles are reset */
}
.dialog::backdrop { background: rgba(27, 24, 20, 0.45); }
.dialog[open] { animation: dialog-in 0.16s ease; }
@keyframes dialog-in {
  from { opacity: 0; transform: translateY(-6px); }
}
.dialog__head { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }
.dialog__head i { font-size: 19px; }
.dialog--danger .dialog__head { color: var(--accent); }
.dialog__title { font-family: var(--font-ui); font-weight: 700; font-size: 15px; }
.dialog--danger .dialog__title { color: var(--accent); }
.dialog__body { font-size: 13.5px; line-height: 1.6; color: var(--muted); max-width: 52ch; }
.dialog__body + .dialog__body { margin-top: 10px; }
.dialog__field { margin-top: 16px; }
.dialog__actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; }
.dialog__actions .btn { font-size: 12.5px; padding: 9px 16px; }
.dialog__actions .btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
.dialog__actions .btn--primary:disabled:hover { background: var(--accent); }
