/* App shell, forms and layout — everything the design system's components.css does not cover.
   Reads only tokens.css custom properties and its type-scale classes. */

/* Restated here, defensively: components.css declares the same universal rule,
   but its effect wasn't computing in testing (every element read back as
   content-box despite the served file having the rule) — cause not pinned down.
   app.css loads last, so this wins regardless; every width:100% + padding/border
   combination in the app (inputs, cards, .ubf-slot in an agenda list, …)
   depends on this actually being border-box. */
* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--surface-100);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 20px;
}

a { color: var(--brand-primary); text-decoration: none; }
a:hover { color: var(--brand-primary-hover); text-decoration: underline; }
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

h1, h2, h3 { margin: 0; font-family: var(--font-display); font-weight: 600; }

/* --- header ------------------------------------------------------------- */

.app-header {
  background: var(--surface-200);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 20;
}
.app-header__inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--space-3) var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
/* The design system sets 96px as the wordmark's minimum width; the height follows
   from the lockup's own proportions rather than being squeezed to fit the bar. */
.app-header__logo img { display: block; width: 96px; height: auto; }
.app-nav { display: flex; align-items: center; gap: var(--space-2); flex: 1; }
.app-nav__link {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--ink);
  font-weight: 600;
  white-space: nowrap;
}
.app-nav__link:hover { background: var(--surface-300); text-decoration: none; }
.app-nav__link--active { color: var(--brand-primary); background: var(--brand-primary-subtle); }
.app-header__tools { display: flex; align-items: center; gap: var(--space-3); }

.app-header__burger {
  display: none;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-2);
  color: var(--ink);
  cursor: pointer;
}

/* --- menus (user menu, language switcher, bell dropdown) ----------------- */

.menu { position: relative; }
.menu__trigger {
  background: none;
  border: none;
  padding: var(--space-1);
  cursor: pointer;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  border-radius: var(--radius-md);
}
.menu__trigger:hover { background: var(--surface-300); }
.menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-2));
  min-width: 220px;
  background: var(--surface-200);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  padding: var(--space-2);
  z-index: 30;
}
.menu__item {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border: none;
  background: none;
  border-radius: var(--radius-md);
  color: var(--ink);
  cursor: pointer;
  font: inherit;
}
.menu__item:hover { background: var(--surface-300); text-decoration: none; }
.menu__item--current { color: var(--brand-primary); font-weight: 600; }
.menu__header { padding: var(--space-2) var(--space-3); color: var(--ink-secondary); }
.menu__divider { height: 1px; background: var(--border); margin: var(--space-2) 0; border: 0; }

/* --- page --------------------------------------------------------------- */

.page { max-width: 1200px; margin: 0 auto; padding: var(--space-6) var(--space-4) var(--space-8); }
.page__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
  flex-wrap: wrap;
}
.page__title { color: var(--ink); }
.page__subtitle { color: var(--ink-secondary); margin-top: var(--space-2); }
.page__actions { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.section { margin-top: var(--space-6); }
.section__title { color: var(--ink); margin-bottom: var(--space-4); }

.stack { display: flex; flex-direction: column; gap: var(--space-4); }
.stack--tight { gap: var(--space-2); }
.row { display: flex; align-items: center; gap: var(--space-3); }
.row--wrap { flex-wrap: wrap; }
.row--between { justify-content: space-between; }
.muted { color: var(--ink-secondary); }
.spacer { flex: 1; }

/* --- empty state -------------------------------------------------------- */

.empty-state {
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-7) var(--space-5);
  text-align: center;
  color: var(--ink-secondary);
  background: var(--surface-200);
}
.empty-state__title { color: var(--ink); margin-bottom: var(--space-2); }

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

.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field__label { color: var(--ink-secondary); }
.field__hint { color: var(--ink-secondary); }
.field__error { color: var(--danger); }

.input, .select, .textarea {
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 20px;
  color: var(--ink);
  background: var(--surface-200);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  width: 100%;
}
.textarea { min-height: 120px; resize: vertical; }
.input:disabled, .select:disabled, .textarea:disabled { background: var(--surface-300); color: var(--ink-secondary); }
.input--invalid, .select--invalid, .textarea--invalid { border-color: var(--danger); }

/* Design-system layout rule: a field-adjacent action sits in its own row below
   the last field, never inline against one — so it can never overlap or crowd it. */
.form-actions { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-5); }
.form-actions--end { justify-content: flex-end; }

/* A responsive grid for a form's fields — replaces the old inline-flex rows, whose
   items could refuse to shrink below their content's width and spill past the card. */
.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-4);
  align-items: end;
}
.field-row > .field { min-width: 0; }
.field-row--tight { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-3); }

/* --- flash messages ----------------------------------------------------- */

.flashes { max-width: 1200px; margin: var(--space-4) auto 0; padding: 0 var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.flash {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-200);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.flash--success { background: var(--success-subtle); border-color: var(--success); color: var(--ink); }
.flash--info { background: var(--info-subtle); border-color: var(--info); color: var(--ink); }
.flash--danger { background: var(--danger-subtle); border-color: var(--danger); color: var(--ink); }
.flash--neutral { background: var(--neutral-subtle); border-color: var(--border); color: var(--ink); }

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

.table { width: 100%; border-collapse: collapse; background: var(--surface-200); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
.table th, .table td { text-align: left; padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); vertical-align: middle; }
.table th { color: var(--ink-secondary); }
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--surface-300); }

/* --- auth screen -------------------------------------------------------- */

.auth { min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: var(--space-5); }
.auth__card {
  background: var(--surface-200);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-7) var(--space-6);
  width: min(420px, 100%);
  text-align: center;
}
.auth__logo { height: 72px; width: auto; margin-bottom: var(--space-5); }
.auth__title { margin-bottom: var(--space-3); }
.auth__text { color: var(--ink-secondary); margin-bottom: var(--space-5); }

/* --- footer ------------------------------------------------------------- */

.app-footer { max-width: 1200px; margin: 0 auto; padding: var(--space-5) var(--space-4); color: var(--ink-secondary); border-top: 1px solid var(--border); }

/* --- small screens ------------------------------------------------------ */

@media (max-width: 760px) {
  .app-header__burger { display: inline-flex; }
  .app-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    background: var(--surface-200);
    border-bottom: 1px solid var(--border);
    padding: var(--space-3) var(--space-4);
    gap: var(--space-1);
  }
  .app-nav--open { display: flex; }
  .page { padding: var(--space-5) var(--space-4) var(--space-7); }
  .display-lg { font-size: 26px; line-height: 34px; }
  .display-md { font-size: 20px; line-height: 28px; }
}

/* --- design-system component extensions ---------------------------------
   The design system's bundle.js sets a handful of per-element styles inline.
   The Jinja macros keep its class contract and use these classes instead. */

/* wrap, not nowrap: a long translated status word (e.g. Ukrainian "Заблоковано")
   next to a title has nowhere left to shrink to — letting the badge drop to its
   own line keeps it inside the card instead of overflowing past the border. */
.ubf-card__header { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.ubf-meta-row { display: flex; align-items: center; gap: var(--space-2); color: var(--ink-secondary); }
.ubf-meta-row__due { margin-left: auto; color: var(--ink-secondary); }
.ubf-meta-row__due--overdue { color: var(--danger); }
.ubf-card__stack { display: flex; flex-direction: column; gap: var(--space-3); }
.ubf-stack--1 { display: flex; flex-direction: column; gap: var(--space-1); }
.ubf-stack--2 { display: flex; flex-direction: column; gap: var(--space-2); }
.ubf-stack--3 { display: flex; flex-direction: column; gap: var(--space-3); }
.ubf-checklist-row__box--sm { width: 12px; height: 12px; }
.ubf-panel__label { color: var(--ink-secondary); }
.ubf-swap-arrow { text-align: center; margin: var(--space-2) 0; }
.ubf-poll {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--surface-100);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}
.ubf-poll__header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.ubf-poll-option__header { display: flex; align-items: center; justify-content: space-between; }
.ubf-announcement__footer { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-3); flex-wrap: wrap; }
.ubf-announcement__comment-count { color: var(--ink-secondary); white-space: nowrap; }
/* The design system gives accent exactly three uses, one of them the Invite action;
   bundle.css has no accent button, so the variant lives here. */
.ubf-btn--accent { background: var(--accent); color: var(--on-accent); }
.ubf-btn--accent:hover { background: var(--success); filter: brightness(0.94); }
.ubf-btn--block { width: 100%; justify-content: center; }
.ubf-btn--lg { padding: var(--space-3) var(--space-5); font-size: 15px; }
.ubf-btn[disabled] { opacity: 0.55; cursor: not-allowed; }

[x-cloak] { display: none !important; }

/* --- announcements ------------------------------------------------------ */

.feed .ubf-announcement, .feed .ubf-card { width: auto; }
.detail-column { max-width: 720px; }
.detail-column .ubf-announcement { width: auto; }
.ubf-announcement__body, .comment-text { white-space: pre-wrap; margin: 0; }

/* Tighter than bundle.css's default var(--space-3) — that much gap between five
   reaction buttons was a big part of why the row overflowed narrow cards. */
.ubf-reaction-row { gap: var(--space-1); }

.ubf-reaction--button {
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  padding: var(--space-1) var(--space-2);
  cursor: pointer;
  font: inherit;
}
.ubf-reaction--button:hover { background: var(--surface-300); }
.ubf-reaction--mine { border-color: var(--brand-primary); background: var(--brand-primary-subtle); color: var(--brand-primary); }
.ubf-reaction__emoji { font-size: 14px; line-height: 20px; }

.ubf-poll-option__choose {
  background: none;
  border: none;
  padding: 0;
  text-align: left;
  color: var(--brand-primary);
  cursor: pointer;
  font: inherit;
}
.ubf-poll-option__choose--mine { font-weight: 700; }

.ubf-comment { margin-bottom: var(--space-3); }
.ubf-comment__body .row { margin-bottom: var(--space-1); }
.ubf-comment__body .ubf-reaction-row { margin-top: var(--space-1); }

/* --- duty calendars ----------------------------------------------------- */

/* A vertical list of calendars, each opening its own fill-in column page. */
.calendar-row { display: block; color: var(--ink); }
.calendar-row:hover { text-decoration: none; }

.ubf-slot__actions { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2); margin-top: auto; }
.select--inline { padding: 2px var(--space-2); font-size: 12px; line-height: 16px; }

/* --- projects ----------------------------------------------------------- */

.progress {
  height: 8px;
  border-radius: var(--radius-full);
  background: var(--surface-300);
  overflow: hidden;
}
.progress__fill { height: 100%; background: var(--brand-primary); border-radius: var(--radius-full); }

.project-row { display: flex; flex-direction: column; gap: var(--space-3); color: var(--ink); }
.project-row:hover { text-decoration: none; }

.board-scroll { overflow-x: auto; padding-bottom: var(--space-3); }
/* The vendored component fixes each column at 240px, sized for its own preview
   card. The board always has exactly these four status columns (not an
   open-ended list), so growing them to fill the page reads as intentional
   instead of leaving empty space on the right; the min-width keeps a card's
   contents from getting cramped, and board-scroll's overflow-x is the
   fallback below that on a narrow viewport. */
.ubf-column { flex: 1 1 240px; width: auto; min-width: 240px; }
.task-card__title { color: var(--ink); }
.task-card__title:hover { color: var(--brand-primary); }
.task-card__status { margin-top: var(--space-1); }
.ubf-column__cards { padding: var(--space-1); border-radius: var(--radius-md); }
/* Subtasks nest under their parent's card, indented with a connecting rule —
   visibly grouped instead of invisible off the board entirely. */
.task-card__subtasks {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-left: var(--space-5);
  padding-left: var(--space-3);
  border-left: 2px solid var(--border);
}
.task-card--subtask { padding: var(--space-3); }
.task-panel { width: 100%; max-width: 720px; }

/* A native <input type="file"> renders its own unstyleable browse button
   (e.g. Chrome's "Вибрати файл"), so a styled label triggers it instead. The
   input stays in the DOM and keyboard-focusable — clipped off-screen, not
   display:none, which some browsers treat as unclickable via the label. */
.ubf-file-picker { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.ubf-file-picker__input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.ubf-file-picker label:has(+ .ubf-file-picker__input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
.ubf-attachment__thumb {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  flex: none;
}

@media (max-width: 900px) {
  /* The board stacks into one list per status on small screens (spec section 13). */
  .ubf-board { flex-direction: column; gap: var(--space-5); }
  .ubf-column { width: 100%; }
}

/* --- notifications ------------------------------------------------------ */

.bell { position: relative; }
.bell__icon { display: inline-flex; color: var(--ink); }
.bell__count {
  position: absolute;
  top: -2px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-full);
  background: var(--brand-primary);
  color: var(--on-brand-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.menu__panel--wide { min-width: 340px; max-width: 380px; }
/* Ukrainian labels are long: let the two actions share the row or fall onto two lines. */
.bell__footer { padding: 0 var(--space-2); gap: var(--space-2); flex-wrap: wrap; }
.bell__footer .menu__item { padding: var(--space-2); }
.notification-list { display: flex; flex-direction: column; max-height: 360px; overflow-y: auto; }
.notification {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--ink);
}
.notification:hover { background: var(--surface-300); text-decoration: none; }
.notification--unread { background: var(--brand-primary-subtle); }
.notification__subject { font-weight: 600; }

.notification-row { display: flex; flex-direction: column; gap: var(--space-2); color: var(--ink); }
.notification-row:hover { text-decoration: none; background: var(--surface-300); }
.notification-row--unread { border-color: var(--brand-primary); }

/* --- landing page: horizontally scrolling ribbons ------------------------ */

.section__header { align-items: baseline; margin-bottom: var(--space-4); gap: var(--space-4); }
.section__link { color: var(--brand-primary); white-space: nowrap; }

.ribbon-track {
  display: flex;
  gap: var(--space-4);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: var(--space-2);
  scroll-behavior: smooth;
}
.ribbon-track > * { scroll-snap-align: start; flex: none; }
/* Keep the native scrollbar out of the way visually — the arrow buttons are
   the primary control; trackpad/touch scrolling still works underneath. */
.ribbon-track { scrollbar-width: thin; }

.ribbon-track .ubf-announcement { width: 340px; }

.week-column {
  width: 240px;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.week-column__header { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.week-column__range { color: var(--ink-secondary); }
.week-column--current .week-column__range { color: var(--brand-primary); font-weight: 700; }
/* One badge per day — every duty on it lives inside, instead of each duty
   getting its own card. */
.week-day {
  background: var(--surface-200);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.week-day__date { color: var(--ink-secondary); }
.week-day__duties { display: flex; flex-direction: column; gap: var(--space-2); }
.week-day__duty { display: flex; flex-direction: column; gap: var(--space-2); }
.week-day__duty + .week-day__duty { padding-top: var(--space-2); border-top: 1px solid var(--border); }
.week-column__empty { color: var(--ink-secondary); padding: var(--space-3) 0; }

/* --- projects list (design system: ProjectsList / ProjectsPage) --------- */

/* The design system's own preview fixes this at 480px for its card; the real
   page fills the available width instead. */
.ubf-projects-list { width: auto; max-width: 720px; }
.ubf-project-row { display: block; }

/* --- calendar wizard (design system: CalendarWizard) --------------------- */

.ubf-chip { cursor: pointer; position: relative; }
.ubf-chip input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
/* Reacts live to the radio's checked state — no JS needed to re-style the chip. */
.ubf-chip:has(input:checked) { background: var(--brand-primary-subtle); border-color: var(--brand-primary); color: var(--brand-primary); }
.ubf-chip:has(input:focus-visible) { outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* --- responsive safety net for the design system's fixed-width containers -- */
/* bundle.css sizes these for its own preview cards (.ubf-modal 360px, .ubf-wizard
   400px, .ubf-panel 420px, .ubf-projects-list 480px, .ubf-announcement 380px) —
   comfortable in a preview, but wider than a phone screen. Cap them here instead
   of overriding each one per template. */
.ubf-modal,
.ubf-wizard,
.ubf-panel,
.ubf-projects-list,
.ubf-announcement {
  max-width: 100%;
  box-sizing: border-box;
}

/* --- the unified fill-column (calendar wizard step 3, and the calendar's own
   edit page) ---------------------------------------------------------------- */

.fill-column { max-width: 760px; }
/* The vendored component caps this at 260px with its own scrollbar — fine
   inside a small wizard step, wrong once this is a page's main content. */
.ubf-wizard-dates { max-height: none; overflow-y: visible; }

.fill-row {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border);
  align-items: flex-start;
}
.fill-row:last-child { border-bottom: none; }
.fill-row__date {
  flex: 0 0 140px;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-top: var(--space-2);
  color: var(--ink-secondary);
}
.fill-row__date input.input { width: 140px; }
/* A single event's date is an editable input, not the plain read-only text
   the padding-top above was calibrated for — drop it so the field lines up
   with the assignee/note fields beside it. */
.fill-row__date:has(input[type="date"]) { padding-top: 0; }
.fill-row__fields {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-3);
}

@media (max-width: 640px) {
  .fill-row { flex-direction: column; gap: var(--space-2); }
  .fill-row__date { flex: none; padding-top: 0; }
}
