/* ==========================================================================
   dashboard.css — the first page, and the handover from the mascot
   --------------------------------------------------------------------------
   Two states in one page. In `intro` the mascot has the screen; in `ready` he
   is gone and the cards are there. Both live in the DOM the whole time so the
   swap can be a cross-fade rather than a flash of empty page — and the intro
   is `position: absolute` so it never reserves height it is about to give up.
   ========================================================================== */

.dash { position: relative; min-height: min(70vh, 620px); }

.dash__intro {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 1;
  transition: opacity 520ms var(--ease), transform 520ms var(--ease);
}

.dash__body { transition: opacity 420ms var(--ease) 120ms, transform 420ms var(--ease) 120ms; }

.dash[data-phase="intro"] .dash__body {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  /* Not just invisible: nothing behind the greeting should be tabbable or
     readable by a screen reader while it is still the whole page. */
  visibility: hidden;
}

.dash[data-phase="ready"] .dash__intro {
  opacity: 0;
  transform: translate3d(0, -18px, 0) scale(0.96);
  pointer-events: none;
  visibility: hidden;
  transition: opacity 520ms var(--ease), transform 520ms var(--ease),
              visibility 0s linear 520ms;
}

/* Someone who asked for less motion gets the dashboard immediately — the
   intro is skipped in dashboard.js, and this makes sure nothing fades. */
@media (prefers-reduced-motion: reduce) {
  .dash__intro, .dash__body { transition: none; }
}

/* --------------------------------------------------------------------------
   Header — the greeting keeps a small mascot beside it
   -------------------------------------------------------------------------- */

.dash__header { align-items: center; }

/* --------------------------------------------------------------------------
   "Waar werk je aan?" — between the greeting and the mascot

   The app has just said hello; this is the first thing it wants to know. It
   sits in the space those two were already leaving empty, so the header gains
   a use rather than a row.
   -------------------------------------------------------------------------- */

.dash-ask {
  flex: 0 1 28rem;
  min-width: 0;
  display: grid;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
}

/* Running: the same green the timer uses everywhere else, so "something is
   counting" looks the same wherever you meet it — and WIDER, taking the space
   the header was already leaving empty. It grows sideways, never downwards:
   a strip that gets taller shoves the whole page down every time you start a
   timer. */
.dash-ask--on {
  /* Same basis as idle, grow 1: it takes the free space that is there and
     never asks for more than the header can give, so starting a timer can
     never be what pushes the greeting onto a second row. */
  flex: 1 1 28rem;
  border-color: var(--accent);
  background: var(--accent-soft);
}

/* Only when it just started. The strip is moved back into a freshly built
   header on every repaint, and a re-inserted node restarts its animations —
   without this the widening replayed every time anything on the page
   changed. */
.dash-ask--on.dash-ask--just {
  animation: dash-ask-widen 260ms ease-out;
}

@keyframes dash-ask-widen {
  from { flex-grow: 0; }
  to   { flex-grow: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .dash-ask--on.dash-ask--just { animation: none; }
}

.dash-ask__label {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}

.dash-ask--on .dash-ask__label { color: var(--accent-soft-ink); }

/* Both states are the same height to the pixel, so the header does not hop
   when the timer starts. */
.dash-ask__line {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  min-height: 34px;
}

.dash-ask__pick { flex: 1; min-width: 0; }

.dash-ask__what {
  flex: 1;
  min-width: 0;
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dash-ask__what:hover { text-decoration: underline; text-underline-offset: 3px; }

.dash-ask__clock {
  flex: none;
  font-variant-numeric: tabular-nums;
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--text-primary);
}

.dash-ask__stop { flex: none; }

.dash-ask__dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  animation: dash-ask-pulse 1.8s ease-in-out infinite;
}

@keyframes dash-ask-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
  .dash-ask__stop { flex: none; }

.dash-ask__dot { animation: none; }
}

.dash__mark {
  width: 56px;
  height: auto;
  flex-shrink: 0;
  animation: mascot-float 3.4s ease-in-out infinite alternate;
}

@media (prefers-reduced-motion: reduce) {
  .dash__mark { animation: none; }
}

/* --------------------------------------------------------------------------
   The grid
   -------------------------------------------------------------------------- */

.dash__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
}

/* Cards end where their content ends. Stretching them to the tallest card in
   the row would even up the bottom edge at the cost of a card with a large
   empty belly, which reads as something that failed to load. White space
   between cards does not. */
.dash__grid { align-items: start; }
.dash-card__body { align-content: start; }

.dash-card--wide { grid-column: span 2; }
.dash-card--full { grid-column: 1 / -1; }

.dash-tiles {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-5);
}

/* --------------------------------------------------------------------------
   Tiles — a number and where it takes you
   -------------------------------------------------------------------------- */

.dash-tile {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  box-shadow: var(--shadow-xs);
  color: var(--text-primary);
  text-decoration: none;
  transition: border-color 140ms var(--ease), background 140ms var(--ease);
}

.dash-tile:hover { border-color: var(--border-strong); background: var(--surface-hover); }
.dash-tile:focus-visible { outline: none; border-color: var(--border-focus); box-shadow: var(--focus-ring); }

.dash-tile__icon {
  width: 20px;
  height: 20px;
  padding: 8px;
  box-sizing: content-box;
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  stroke: var(--accent-soft-ink);
  fill: none;
  stroke-width: 1.7;
  flex-shrink: 0;
}

.dash-tile__text { min-width: 0; flex: 1; }
/* nowrap: "19,25 u" breaking across two lines turns a figure into a
   sentence, and the label underneath is allowed to wrap instead. */
.dash-tile__value { font-size: var(--text-xl); font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.15; white-space: nowrap; }

.dash-tile__label {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.dash-tile__go { width: 16px; height: 16px; stroke: var(--text-muted); fill: none; stroke-width: 1.9; flex-shrink: 0; }

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.dash-card__body { display: grid; gap: var(--space-3); }
.dash-card--timer .dash-card__body { padding-top: var(--space-4); }
.dash-card--timer .ts-timer { margin-bottom: 0; }

.card__link {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-link);
  text-decoration: none;
  white-space: nowrap;
}

.card__link:hover { text-decoration: underline; }

.dash-list { display: grid; }
.dash-sub {
  margin-top: var(--space-2);
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.dash-more { font-size: var(--text-xs); color: var(--text-muted); }

.dash-empty {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.dash-empty__icon { width: 16px; height: 16px; stroke: var(--good-ink); fill: none; stroke-width: 2; flex-shrink: 0; }

/* --------------------------------------------------------------------------
   A task row — read it, open it, book on it, talk about it
   -------------------------------------------------------------------------- */

.dash-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border-subtle);
}

.dash-row:last-child { border-bottom: 0; }

.dash-row__main {
  display: grid;
  gap: 1px;
  flex: 1;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.dash-row__main:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }
.dash-row__title { font-size: var(--text-sm); font-weight: 500; line-height: var(--leading-snug); }
.dash-row__main:hover .dash-row__title { color: var(--text-link); }

.dash-row__meta {
  display: flex;
  gap: var(--space-2);
  font-size: var(--text-2xs);
  color: var(--text-muted);
  min-width: 0;
}

.dash-row__meta > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-row__dot { flex-shrink: 0; }

.dash-row__actions { display: flex; gap: 2px; flex-shrink: 0; opacity: 0; transition: opacity 120ms var(--ease); }
.dash-row:hover .dash-row__actions,
.dash-row:focus-within .dash-row__actions { opacity: 1; }

@media (hover: none) { .dash-row__actions { opacity: 1; } }

.dash-due {
  flex-shrink: 0;
  font-size: var(--text-2xs);
  font-weight: 600;
  color: var(--text-muted);
  white-space: nowrap;
}

.dash-due--soon { color: var(--warning-ink); }
.dash-due--late { color: var(--critical-ink); }

/* --------------------------------------------------------------------------
   A project row
   -------------------------------------------------------------------------- */

.dash-proj {
  display: grid;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border-subtle);
  text-decoration: none;
  color: var(--text-primary);
}

.dash-proj:last-child { border-bottom: 0; }
.dash-proj:hover .dash-proj__name { color: var(--text-link); }
.dash-proj:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }

.dash-proj__top { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.dash-proj__name { font-size: var(--text-sm); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dash-proj__foot {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--text-2xs);
  color: var(--text-muted);
}

.dash-proj__due--warn { color: var(--warning-ink); font-weight: 600; }

/* --------------------------------------------------------------------------
   Your week — seven bars, scaled to the busiest day
   -------------------------------------------------------------------------- */

.dash-week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--space-2);
  align-items: end;
}

.dash-week__day { display: grid; gap: var(--space-1); justify-items: center; min-width: 0; padding: var(--space-1) 2px; }
.dash-week__track { display: flex; align-items: flex-end; width: 100%; height: 78px; }

.dash-week__bar {
  width: 100%;
  min-height: 3px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  background: var(--accent);
}

/* A day with nothing on it is a hairline, not a missing column — the shape of
   the week is the point, and gaps in it are information. */
.dash-week__bar--none { background: var(--border-subtle); height: 3px !important; }

.dash-week__name {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.dash-week__num { font-size: var(--text-2xs); font-variant-numeric: tabular-nums; color: var(--text-muted); }

/* Today is marked by the column it sits in, the same way the timesheet marks
   today's column — not by a second shade of the bar colour, which would read
   as a second kind of hour. */
.dash-week__day--today {
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent-soft) 70%, transparent);
}

.dash-week__day--today .dash-week__name,
.dash-week__day--today .dash-week__num { color: var(--accent-soft-ink); font-weight: 600; }

.dash-week__foot { display: flex; align-items: baseline; gap: var(--space-2); padding-top: var(--space-2); border-top: 1px solid var(--border-subtle); }
.dash-week__total { font-size: var(--text-xl); font-weight: 600; font-variant-numeric: tabular-nums; }
.dash-week__against { font-size: var(--text-xs); color: var(--text-muted); }
.dash-week__write { justify-self: start; }

/* --------------------------------------------------------------------------
   Conversations and colleagues
   -------------------------------------------------------------------------- */

.dash-convo,
.dash-person {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-2) 0;
  border: 0;
  border-bottom: 1px solid var(--border-subtle);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
}

.dash-convo:last-child, .dash-person:last-child { border-bottom: 0; }
.dash-convo { cursor: pointer; }
.dash-convo:hover .dash-convo__name { color: var(--text-link); }
.dash-convo:focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--radius-sm); }

.dash-convo__text, .dash-person__text { display: grid; gap: 1px; flex: 1; min-width: 0; }
.dash-convo__name, .dash-person__name { font-size: var(--text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-convo__preview, .dash-person__meta { font-size: var(--text-2xs); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-convo--unread .dash-convo__name { font-weight: 600; }
.dash-convo--unread .dash-convo__preview { color: var(--text-secondary); font-weight: 500; }

.dash-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
.dash-fact__value { font-size: var(--text-xl); font-weight: 600; font-variant-numeric: tabular-nums; }
.dash-fact__label { font-size: var(--text-2xs); font-weight: 600; letter-spacing: var(--tracking-wide); text-transform: uppercase; color: var(--text-muted); }

/* --------------------------------------------------------------------------
   Responsive — three columns, then two, then one
   -------------------------------------------------------------------------- */

@media (max-width: 1200px) {
  .dash__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-card--wide { grid-column: span 2; }
}

@media (max-width: 760px) {
  .dash__grid { grid-template-columns: minmax(0, 1fr); }
  .dash-card--wide { grid-column: span 1; }
  .dash__mark { display: none; }
  .dash-ask { flex: 1 1 100%; }
  .dash-week__track { height: 62px; }

  /* A task row is four things fighting over 320 pixels. Give the title the
     whole width and put the deadline and the buttons on a line of their own,
     rather than truncating the one thing you came to read. */
  .dash-row { flex-wrap: wrap; row-gap: var(--space-1); }
  .dash-row__main { flex: 1 1 100%; }
  .dash-due { order: 2; }
  .dash-row__actions { order: 3; margin-left: auto; opacity: 1; }

  /* Same idea for the timer: the project you pick and the button that starts
     it belong side by side, not stacked with the button adrift. */
  .dash-card--timer .ts-timer .select { flex: 1; max-width: none; }
}
