/* ---------------------------------------------------------------------------
   The shell: ambient ground, sidebar/main split, top bar, and the glass card
   every section is built out of. Section contents live in styles/components/.
   --------------------------------------------------------------------------- */

/* --- ambient ground ------------------------------------------------------- */
/* Fixed, so panels slide over it instead of dragging it along, and behind
   everything so it never intercepts a pointer.

   The two lower blooms are centred past the bottom edge on purpose. Sat at
   96%/98% they landed exactly on the bottom corners of the cards — so the
   notch a rounded corner leaves showed the bloom at full strength while the
   card beside it showed the same bloom through 60% white, and the step across
   that 18px arc was what made a corner read as a chip out of the layout. Off
   the edge, only the falloff reaches the bottom and it arrives evenly. */

.ambient {
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(58% 46% at 10% 6%,   var(--mesh-a), transparent 68%),
    radial-gradient(52% 42% at 92% 2%,   var(--mesh-b), transparent 68%),
    radial-gradient(72% 62% at 78% 118%, var(--mesh-c), transparent 70%),
    radial-gradient(56% 54% at 22% 122%, var(--mesh-d), transparent 70%),
    var(--ground);
}

/* --- shell ---------------------------------------------------------------- */

/* Capped and centred rather than filling whatever display it lands on. See
   --board in tokens.css for why. The ambient ground is fixed to the viewport
   and sits behind this, so the space either side is the background and not a
   margin. */
.app {
  display: grid;
  grid-template-columns: 228px minmax(0, 1fr);
  gap: var(--shell);
  padding: var(--shell);
  max-width: var(--board);
  margin-inline: auto;
  min-height: 100vh;
  align-items: start;
  transition: grid-template-columns .34s var(--ease);
}

.app.collapsed { grid-template-columns: 62px minmax(0, 1fr); }

.main {
  display: flex;
  flex-direction: column;
  gap: var(--shell);
  min-width: 0;
  height: calc(100vh - var(--shell) * 2);
}

/* --- glass card ----------------------------------------------------------- */

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--glass);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  box-shadow: var(--glass-shadow);
}

/* The rim. A gradient ring masked to a 1px band: bright along the top edge
   where light would catch, settling to a neutral hairline further down. */
/* z-index clears the sticky calendar chrome inside the card: the rim is the
   card's outer edge and nothing may paint over it. */
.card::after,
.topbar::after,
.sidebar::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 10;
  pointer-events: none;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    170deg,
    var(--glass-hi) 0%,
    var(--glass-edge) 38%,
    var(--glass-edge) 100%
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}

.card-head {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: none;
  padding: 11px 14px;
  border-bottom: 1px solid var(--hair);
}

.card-head h2 {
  font-size: 13px;
  font-weight: 650;
  letter-spacing: .01em;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.head-ico {
  display: grid;
  place-content: center;
  color: var(--muted);
  flex: none;
}

/* --- top bar -------------------------------------------------------------- */

.topbar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 24px;
  flex: none;
  padding: 11px 18px;
  border-radius: var(--r-lg);
  background: var(--glass);
  -webkit-backdrop-filter: var(--blur);
  backdrop-filter: var(--blur);
  box-shadow: var(--glass-shadow);
}

/* The mark sits with the name of the board rather than the name of the
   software.

   No border-radius, no ring, no box-shadow: the artwork brings its own
   rounded-square shape on a transparent surround, so all three would trace the
   *element box* instead — an inset hairline floating in the corners the art
   deliberately leaves empty, and a shadow cast by a rectangle nothing draws.
   `drop-shadow` follows the alpha channel, so it hugs the shape.

   `contain`, because that transparent margin is part of the artwork and
   `cover` would crop it off on any source that is not exactly square. Sized a
   little larger than the old flat panel to make up for it optically. */
.tb-mark {
  width: 34px;
  height: 34px;
  flex: none;
  margin-right: -14px;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px rgba(20, 30, 45, .30));
}

.tb-title { min-width: 0; }

.tb-title h1 {
  font-size: 17px;
  font-weight: 640;
  letter-spacing: -.015em;
  line-height: 1.25;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tb-sub {
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- weather -------------------------------------------------------------- */

/* Beside the title, not among the counters: it is the one thing on this bar
   that is not about your own work, and it should not read as a fifth statistic.
   Hidden entirely until there is a reading — an empty slot saying nothing is
   worse than no slot. */
.weather {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  max-width: 190px;
  padding: 4px 11px 5px;
  border-radius: var(--r-pill);
  background: var(--fill-2);
  text-align: left;
  cursor: pointer;
  transition: background .16s ease, opacity .16s ease;
}

.weather:hover { background: var(--hover); }
.weather[hidden] { display: none; }

/* An hour-old reading is still worth showing, but not worth trusting to the
   minute — so it says so by fading rather than by disappearing. */
.weather.is-stale { opacity: .55; }

.weather .w-ico {
  display: grid;
  place-content: center;
  flex: none;
  color: var(--muted);
}

.weather .w-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.weather .w-line {
  display: flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
}

.weather .w-temp {
  font-size: 13px;
  font-weight: 550;
  color: var(--ink);
}

.weather .w-label,
.weather .w-place {
  font-size: 10px;
  color: var(--faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.weather .w-label { color: var(--muted); }

/* The clock cluster: weekday, ISO date, ISO week, stacked tight. */
.tb-date {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 3px 11px;
  border-radius: var(--r-pill);
  background: var(--fill-2);
  white-space: nowrap;
}

.tb-date .dow { font-size: 11.5px; font-weight: 600; color: var(--ink-2); }
.tb-date .day { font-size: 12px; color: var(--ink-2); }
.tb-date .week { font-size: 10px; letter-spacing: .04em; color: var(--faint); }

.stats {
  display: flex;
  gap: 22px;
  flex: none;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 46px;
}

.stat .n {
  font-size: 19px;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--ink);
}

/* Overdue only earns color when there is something to be alarmed about. */
.stat .n.is-alert { color: var(--danger); }

/* And the one number worth being pleased about, once there is anything in it.
   The pair is what makes the row scan: red and green are the two that mean
   something, and the other two are just figures. */
.stat .n.is-good { color: var(--ok); }

.stat .k {
  font-size: 9.5px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--faint);
  white-space: nowrap;
}

/* --- sections ------------------------------------------------------------- */

.view {
  flex: 1;
  min-height: 0;
}

/* Beats `.view` on specificity, so hiding does not need !important. */
.view[hidden] { display: none; }

#viewToday,
#viewProjects,
#viewAbout {
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: 2px;
}

.ws {
  display: grid;
  grid-template-columns: minmax(272px, 330px) minmax(0, 1fr);
  gap: var(--shell);
  align-items: stretch;
  overflow: hidden;
}

.ws > .card { height: 100%; }

/* Both columns scroll internally, so neither may grow past the row. */
.col-tasks,
.col-calendar { min-height: 0; }

/* --- breakpoints ---------------------------------------------------------- */

/* The calendar needs the width more than the task list does, so the list goes
   first; below that everything stacks and the page scrolls normally. */
@media (max-width: 1080px) {
  .ws { grid-template-columns: minmax(240px, 290px) minmax(0, 1fr); }
  .stats { gap: 16px; }
  .tb-date .week { display: none; }
  /* The temperature is the part worth the width; the place is context. */
  .weather .w-place { display: none; }
}

/* Narrow enough that the rail has to collapse whether or not you asked it to.
   The same set of rules as `.app.collapsed`, applied by width instead — the
   class is not on the element here, so they cannot be inherited from it. */
@media (max-width: 880px) {
  .app { grid-template-columns: 62px minmax(0, 1fr); }
  .app .nav-item .lbl,
  .app .side-btn .lbl,
  .app .sp-title,
  .app .sp-head .tally,
  .app .sp-name,
  .app .sp-n,
  .app .sp-none,
  .app .sp-arch-bar .lbl,
  .app .sp-arch-bar .tally,
  .app .brand { display: none; }
  .app .nav-item,
  .app .side-btn,
  .app .sp-item,
  .app .sp-arch-bar,
  .app .sp-head { justify-content: center; }
}

@media (max-width: 780px) {
  /* Tighter, and the radius comes down with it — the two are a pair, and a
     corner scooping out more than the margin around it is what makes the
     leftover background read as a wedge. */
  .app { --shell: 12px; --r-lg: 12px; }
  .main { height: auto; min-height: calc(100vh - var(--shell) * 2); }
  .topbar { flex-wrap: wrap; gap: 12px 18px; }
  .weather { order: 4; }
  .tb-date { margin-left: 0; order: 3; }
  .stats { order: 2; margin-left: auto; }
  .view { overflow: visible; }
  .ws {
    grid-template-columns: minmax(0, 1fr);
    overflow: visible;
  }
  .ws > .card { height: auto; }
  .ws > .col-calendar { min-height: 520px; }
}
