/* ---------------------------------------------------------------------------
   Components. Every value here comes from tokens.css - no literal colours.

   Logical properties (margin-inline-start, not margin-left) throughout. The UI
   is English-only in v1, but logical properties cost nothing and mean the
   Arabic RTL mirror is a stylesheet change rather than a rewrite.
--------------------------------------------------------------------------- */

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

/* A hidden element must stay hidden. A later rule that sets `display` beats
   [hidden] otherwise, which is how an invisible overlay ends up swallowing
   every click on the page. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--font);
  font-size: var(--text-base);
  color: var(--body);
  background: var(--bg);
  line-height: 1.5;
}

h1, h2, h3 { color: var(--ink); font-weight: var(--weight-bold); margin: 0; }
h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }

a { color: var(--blue-link); }

/* ------------------------------------------------------------------ layout */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  inline-size: var(--sidebar-width);
  flex: 0 0 var(--sidebar-width);
  background: var(--navy-deep);
  color: #cfd9ea;
  padding: var(--space-5) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* The logo is dark grey and navy artwork on a transparent background. Dropped
   straight onto the navy sidebar, 74% of its pixels fall below 4.5:1 contrast
   and the "CxO" mark effectively disappears. It sits on a white chip instead,
   which keeps the brand artwork untouched and legible. Same reason the vault
   app bakes a background behind the logo in its emails. */
.sidebar .lockup { display: block; }
.sidebar .lockup img {
  display: block;
  inline-size: 100%;
  max-inline-size: 152px;
  block-size: auto;
  background: #ffffff;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
}
.sidebar .lockup span {
  display: block;
  margin-block-start: var(--space-3);
  color: #ffffff;
  font-weight: var(--weight-medium);
  font-size: var(--text-sm);
  line-height: 1.25;
}

.sidebar nav { display: flex; flex-direction: column; gap: 2px; }
.sidebar nav button {
  all: unset;
  cursor: pointer;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  color: #cfd9ea;
}
.sidebar nav button:hover { background: rgba(255, 255, 255, 0.08); }
.sidebar nav button[aria-current="page"] {
  background: var(--blue);
  color: #ffffff;
  font-weight: var(--weight-medium);
}

.sidebar .who {
  margin-block-start: auto;
  border-block-start: 1px solid rgba(255, 255, 255, 0.12);
  padding-block-start: var(--space-4);
  font-size: var(--text-xs);
}
.sidebar .who strong { color: #ffffff; display: block; font-size: var(--text-sm); }
.sidebar .who .linkish {
  all: unset;
  cursor: pointer;
  color: var(--cyan);
  font-size: var(--text-xs);
  margin-block-start: var(--space-2);
  display: inline-block;
}
.sidebar .who .linkish:hover { text-decoration: underline; }

.secret {
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  letter-spacing: 0.08em;
  background: var(--navy-soft);
  color: var(--navy);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  display: inline-block;
  user-select: all;
}

.main { flex: 1; min-inline-size: 0; padding: var(--space-5) var(--space-6); }
.main > header { margin-block-end: var(--space-5); }
.main > header p { color: var(--muted); margin: var(--space-1) 0 0; }

/* ------------------------------------------------------------------- cards */

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
  margin-block-end: var(--space-5);
}
.card > h3 { margin-block-end: var(--space-4); }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-4); }
.tile {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.tile .value { font-size: var(--text-2xl); font-weight: var(--weight-bold); color: var(--navy); }
.tile .label { font-size: var(--text-xs); color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }

/* ------------------------------------------------------------------ tables */
/* Dense and scannable. This is a compliance tool used all day, not a brochure. */

table { inline-size: 100%; border-collapse: collapse; font-size: var(--text-sm); }
thead th {
  text-align: start;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  font-weight: var(--weight-medium);
  padding: var(--space-2) var(--space-3);
  border-block-end: 1px solid var(--line);
  white-space: nowrap;
}
tbody td { padding: var(--space-2) var(--space-3); border-block-end: 1px solid var(--line-soft); }
tbody tr:hover { background: var(--navy-soft); }
td.num, th.num { text-align: end; font-variant-numeric: tabular-nums; }
.table-scroll { overflow-x: auto; }

/* ----------------------------------------------------------- traffic light */

.status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px var(--space-2);
  border-radius: 999px;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}
.status .icon { font-family: var(--font-mono); font-weight: var(--weight-bold); }

.status.red    { color: var(--status-expired);   background: var(--status-expired-bg); }
.status.amber  { color: var(--status-due-soon);  background: var(--status-due-soon-bg); }
.status.yellow { color: var(--status-upcoming);  background: var(--status-upcoming-bg); }
.status.green  { color: var(--status-valid);     background: var(--status-valid-bg); }
.status.grey   { color: var(--status-missing);   background: var(--status-missing-bg); }

.pill {
  display: inline-block;
  padding: 1px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--navy-soft);
  color: var(--navy);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
}
.pill.warn { background: var(--status-due-soon-bg); color: var(--status-due-soon); }

/* ------------------------------------------------------------------ forms */

label { display: block; font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--ink); margin-block-end: var(--space-1); }
input[type="text"], input[type="email"], input[type="password"], select, textarea {
  inline-size: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid #d5dde7;
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: var(--text-base);
  color: var(--ink);
  background: #ffffff;
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--cyan);
  outline-offset: 1px;
  border-color: var(--blue);
}
.field { margin-block-end: var(--space-4); }
.hint { font-size: var(--text-xs); color: var(--muted); margin-block-start: var(--space-1); }

/* No inline style attributes anywhere: the Content-Security-Policy sets
   style-src 'self', which blocks them. Weakening the policy to allow one
   checkbox would be the wrong trade. */
.checkbox-row { font-weight: var(--weight-normal); cursor: pointer; }
.checkbox-row input { inline-size: auto; margin-inline-end: var(--space-2); }

button.primary, button.ghost {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  cursor: pointer;
  border: 1px solid transparent;
}
button.primary { background: var(--brand-accent); color: #ffffff; }
button.primary:hover:not(:disabled) { background: var(--navy); }
button.ghost { background: #ffffff; color: var(--navy); border-color: #d5dde7; }
button.ghost:hover:not(:disabled) { background: var(--navy-soft); }
button:disabled { opacity: 0.55; cursor: not-allowed; }

/* ---------------------------------------------------------------- notices */

.notice {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  font-size: var(--text-sm);
  margin-block-end: var(--space-4);
  border: 1px solid var(--line);
  border-inline-start: 4px solid var(--muted);
}
.notice.info { background: var(--blue-soft);      border-inline-start-color: var(--blue);            color: #10456f; }
.notice.warn { background: var(--status-due-soon-bg); border-inline-start-color: var(--status-due-soon); color: var(--status-due-soon); }
.notice.err  { background: var(--burgundy-soft);  border-inline-start-color: var(--burgundy);        color: var(--burgundy); }
.notice.good { background: var(--teal-soft);      border-inline-start-color: var(--teal);            color: var(--status-valid); }

/* ------------------------------------------------------------------ login */

.login-page {
  min-block-size: 100vh;
  display: grid;
  place-items: center;
  background: var(--navy-deep);
  padding: var(--space-4);
}
.login-card {
  inline-size: min(400px, 100%);
  background: var(--card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: var(--space-6);
}
.login-card .lockup { text-align: center; margin-block-end: var(--space-5); }
.login-card .lockup img { block-size: 46px; }
.login-card .lockup h1 { font-size: var(--text-lg); margin-block-start: var(--space-3); }
.login-card .lockup p { color: var(--muted); font-size: var(--text-sm); margin: var(--space-1) 0 0; }
.login-card button.primary { inline-size: 100%; }

/* ----------------------------------------------------------------- tables+ */

tbody tr.clickable { cursor: pointer; }
th.pick, td.pick { inline-size: 28px; }
td.pick input { inline-size: auto; }
td.empty { text-align: center; color: var(--muted); padding: var(--space-5); }
td.group {
  background: var(--navy-soft);
  color: var(--navy);
  font-weight: var(--weight-medium);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
td.actions { white-space: nowrap; }
td.actions > * { margin-inline-end: var(--space-1); }

/* Attribute chips. Only the non-default ones are rendered, so this column
   stays narrow on the common row and still wraps rather than widening the
   table when a type genuinely has several. */
td.details { white-space: normal; min-inline-size: 110px; }
td.details > * { margin-inline-end: var(--space-1); margin-block-end: 2px; }

/* Edit and Delete stay reachable even when a table does still scroll sideways.
   Reaching a Delete button by dragging a horizontal scrollbar is the kind of
   thing people give up on and ask someone else to do for them. */
th.stick-end, td.stick-end {
  position: sticky;
  inset-inline-end: 0;
  background: var(--card);
  /* Without a shadow the columns sliding underneath look like they belong to
     the sticky cell. */
  box-shadow: -8px 0 8px -8px rgba(0, 32, 96, 0.25);
}
thead th.stick-end { z-index: 2; }
tbody tr:hover td.stick-end { background: var(--navy-soft); }
tbody tr.inactive td.stick-end { background: var(--card); }
.badges { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-block: var(--space-2); }

/* ------------------------------------------------------------------ meter */

.meter-row { display: flex; align-items: center; gap: var(--space-2); }
.meter {
  inline-size: 72px;
  block-size: 6px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
  flex: none;
}
.meter-fill { display: block; block-size: 100%; }
.meter-fill.good { background: var(--status-valid); }
.meter-fill.warn { background: var(--status-due-soon); }
.meter-fill.bad  { background: var(--status-expired); }
.meter-label { font-size: var(--text-xs); color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------- toolbar */

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-block-end: var(--space-4);
}
.toolbar input[type="search"] { inline-size: 240px; }
.toolbar select { inline-size: auto; }
.toolbar .spacer { flex: 1; }

.row-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-block-start: var(--space-3); }
button.small, a.small { padding: 2px var(--space-2); font-size: var(--text-xs); }
a.ghost {
  display: inline-block;
  text-decoration: none;
  background: #ffffff;
  color: var(--navy);
  border: 1px solid #d5dde7;
  border-radius: var(--radius);
  font-weight: var(--weight-medium);
}
a.ghost:hover { background: var(--navy-soft); }
.danger-text { color: var(--status-expired); }
.err-text { color: var(--status-expired); font-size: var(--text-xs); }
button.linkish {
  all: unset;
  cursor: pointer;
  color: var(--blue-link);
  font-size: var(--text-sm);
}
button.linkish:hover { text-decoration: underline; }
button.back { margin-block-end: var(--space-2); display: inline-block; }

/* --------------------------------------------------------------- dropzone */

.dropzone {
  border: 2px dashed #c3d3e6;
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  text-align: center;
  color: var(--muted);
  font-size: var(--text-sm);
  background: linear-gradient(180deg, #fbfdff 0%, #f4f8fd 100%);
  margin-block-end: var(--space-4);
}
.dropzone.over { border-color: var(--cyan); background: var(--blue-soft); color: var(--navy); }

/* ----------------------------------------------------------------- drawer */

.drawer-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 24, 69, 0.45);
  display: flex;
  justify-content: flex-end;
  z-index: 50;
}
/* The panel itself does not scroll — only its body does. The employee form has
   27 fields, and with the whole panel scrolling the Save button ended up
   1234px down a 720px viewport: present, but invisible until you scrolled
   575px looking for it. Title and buttons now stay put. */
.drawer {
  background: var(--card);
  inline-size: min(640px, 100%);
  block-size: 100%;
  overflow: hidden;
  padding: var(--space-5);
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.drawer > header { display: flex; align-items: center; gap: var(--space-3); flex: none; }
.drawer > header h2 { flex: 1; font-size: var(--text-lg); }
.drawer > .notice { flex: none; }
#drawer-body {
  flex: 1;
  overflow-y: auto;
  /* Without this a flex child refuses to shrink below its content and the
     overflow silently moves back to the panel. */
  min-block-size: 0;
}
.drawer > footer {
  flex: none;
  display: flex;
  gap: var(--space-2);
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--line);
}

.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 var(--space-4); }

/* --------------------------------------------------------- catalog editor */

.flags { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 0 var(--space-4); }

/* One applicability rule per row. It wraps rather than scrolling, because a
   rule read half-off the side of a drawer is a rule nobody checks. */
.rules { display: flex; flex-direction: column; gap: var(--space-2); }
.rule-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--blue);
  border-radius: var(--radius);
  background: var(--bg);
}
.rule-row select, .rule-row input { inline-size: auto; flex: 1 1 150px; min-inline-size: 0; }

tbody tr.inactive { opacity: 0.55; }
code.hint {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--muted);
  /* An unbreakable 30-character identifier such as
     resignation_termination_letter sets a floor on the column width and was
     the last thing keeping the table wider than its card. */
  overflow-wrap: anywhere;
}

.facts { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1) var(--space-4); margin: 0; }
.facts dt { color: var(--muted); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; }
.facts dd { margin: 0; }

.preview {
  inline-size: 100%;
  block-size: 60vh;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
}
img.preview { block-size: auto; max-block-size: 60vh; object-fit: contain; }

/* ------------------------------------------------------------- responsive */
/* Down to tablet the sidebar collapses to a top bar. Bulk upload stays
   desktop-only by design; the dashboard and expiry list must work small. */

/* Between a laptop screen and a wide monitor the tables are only tens of pixels
   too wide. Tightening the cell padding buys ~48px across six columns, which is
   enough to remove the sideways scroll entirely rather than merely making it
   short. */
@media (max-width: 1200px) {
  thead th, tbody td { padding-inline: var(--space-2); }
  .toolbar input[type="search"] { inline-size: 180px; }
}

@media (max-width: 900px) {
  .shell { flex-direction: column; }
  .sidebar {
    inline-size: 100%;
    flex: none;
    flex-direction: row;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    overflow-x: auto;
  }
  .sidebar nav { flex-direction: row; }
  .sidebar .lockup { display: flex; align-items: center; gap: var(--space-3); }
  .sidebar .lockup img { inline-size: auto; block-size: 30px; padding: 3px var(--space-2); }
  .sidebar .lockup span { display: none; }
  .sidebar .who { margin-block-start: 0; border: none; padding-block-start: 0; margin-inline-start: auto; }
  .main { padding: var(--space-4); }
}

@media print {
  .sidebar { display: none; }
  .card { box-shadow: none; border-color: #999; }
  .status { border: 1px solid currentColor; }
}

/* Audit detail can be a long diff string. Let it wrap and cap the column so it
   cannot push the rest of the table off the side. */
td.detail-cell {
  white-space: normal;
  max-inline-size: 340px;
  font-size: var(--text-xs);
  color: var(--body);
}
.toolbar input[type="date"] { inline-size: auto; }
