/* base.css — reset, typography and the application shell (window/sidebar/content). */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

/* A class that sets `display` would otherwise beat the UA rule for [hidden],
   leaving elements the JS thinks are hidden fully visible. */
[hidden] { display: none !important; }

/* No scrollbar is ever drawn, anywhere. Scrolling itself is untouched — wheel,
   trackpad, touch, keyboard and scrollIntoView all behave exactly as before;
   only the track and thumb stop being painted. */
* {
  scrollbar-width: none;        /* Firefox */
  -ms-overflow-style: none;     /* legacy Edge */
}
*::-webkit-scrollbar {          /* Chrome, Safari, Edge */
  width: 0;
  height: 0;
  display: none;
}

body {
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.45;
  color: var(--text);
  /* No background here on purpose: the .bg layer stack (appearance.css) paints
     it. Painting on <body> propagates to the canvas, which would sit under the
     stack and defeat every mode except "do tema". */
  background: transparent;
  height: 100dvh;
  overflow: hidden;              /* only .content scrolls */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--ui-accent); text-decoration: none; }
h1, h2, h3, h4, p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

/* Numeral alignment via tabular figures on the SAME San Francisco family used
   everywhere else — not a monospace typeface switch. Native macOS apps (Stocks,
   Weather, Numbers) never swap fonts for numbers; only digit widths lock to a
   fixed measure so values don't jitter as they update. */
.mono { font-variant-numeric: tabular-nums; }

:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--ui-accent) 55%, transparent);
  outline-offset: 2px;
  border-radius: 5px;
}

/* --- App shell (full screen) ------------------------------------------------ */
.window {
  width: 100%;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* --- Title bar ------------------------------------------------------------- */
.titlebar {
  /* The bar has to clear the phone's status bar. Installed on an iPhone the page
     is drawn under it — apple-mobile-web-app-status-bar-style is
     black-translucent, and viewport-fit=cover hands us the whole screen — so
     without this the clock and the battery are painted directly on top of the
     logo and the icons. env() is 0 everywhere else, so the desktop is untouched. */
  height: calc(54px + env(safe-area-inset-top));
  flex: 0 0 calc(54px + env(safe-area-inset-top));
  padding-top: env(safe-area-inset-top);
  /* z-index here makes this a stacking context, so the bell popover's own
     z-index is scoped to it. Lift the whole bar above .workspace, otherwise
     the popover renders behind the content panels. */
  position: relative;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: 0 var(--space-4);
  padding-left: max(var(--space-4), env(safe-area-inset-left));
  padding-right: max(var(--space-4), env(safe-area-inset-right));
  background: var(--sidebar);
  backdrop-filter: var(--panel-blur, none);
  -webkit-backdrop-filter: var(--panel-blur, none);
  border-bottom: 1px solid var(--panel-border);
}
/* Icon + wordmark as one lockup. The icon is the favicon file itself, not a
   copy of its paths: one source means the tab and the bar can never drift apart.
   Its alt is empty on purpose — the wordmark right beside it already names the
   app, and a filled alt would have a screen reader say "DayFlow" twice. */
.titlebar__brand { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.titlebar__mark {
  width: 28px; height: 28px; flex: 0 0 28px; display: block;
  /* drop-shadow, not box-shadow: the icon's corners are rounded inside the SVG,
     so a box shadow would draw a square behind a rounded mark. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .28));
}
/* Sized against the mark, not picked in isolation: at 21px against a 28px icon
   the ratio lands at 1.33, which is where the pair stops reading as "an icon
   with some text next to it" and starts reading as one object. Smaller icons
   also squeeze the calendar drawing inside the mark until it turns to mush. */
.titlebar__title { font-size: 21px; font-weight: 600; letter-spacing: -.022em; line-height: 1; }
/* "Flow" carries the brand blue — the same hex as the app icon's background. */
.titlebar__title-accent { color: var(--brand); }
.titlebar__tools { display: flex; align-items: center; gap: var(--space-1); }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: none; background: transparent;
  border-radius: var(--radius-sm); color: var(--text-2); cursor: pointer;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.icon-btn:hover { background: var(--field); color: var(--text); }
.icon-btn svg { width: 17px; height: 17px; }

/* Theme toggle: three icons stacked in the button, CSS picks the one that
   matches data-theme-pref (already set pre-paint, see the inline script in
   base.html — no flash, no JS needed to swap the glyph itself). */
.theme-icon { display: none; }
[data-theme-pref="light"] .theme-icon--light,
[data-theme-pref="dark"]  .theme-icon--dark,
[data-theme-pref="auto"]  .theme-icon--auto { display: inline-flex; }

/* --- Workspace: sidebar + content ----------------------------------------- */
.workspace { flex: 1; display: flex; min-height: 0; }

.sidebar {
  width: 208px;
  flex: 0 0 208px;
  background: var(--sidebar);
  backdrop-filter: var(--panel-blur, none);
  -webkit-backdrop-filter: var(--panel-blur, none);
  border-right: 1px solid var(--panel-border);
  padding: var(--space-4) var(--space-3);
  padding-left: max(var(--space-3), env(safe-area-inset-left));
  padding-bottom: max(var(--space-4), env(safe-area-inset-bottom));
  overflow-y: auto;
}
/* Roomier navigation on large displays now that the app fills the screen. */
@media (min-width: 1600px) {
  .sidebar { width: 240px; flex: 0 0 240px; }
}
.nav-group { margin-bottom: var(--space-5); }
.nav-group__label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-3);
  padding: 0 var(--space-2); margin-bottom: var(--space-2);
}
.nav-item {
  display: flex; align-items: center; gap: var(--space-2);
  padding: 7px var(--space-2); border-radius: var(--radius-sm);
  color: var(--text); font-size: 14px; font-weight: 500;
  cursor: pointer; transition: background .12s var(--ease);
  margin-bottom: 2px;
}
.nav-item:hover { background: var(--field); }
.nav-item.is-active { background: var(--ui-accent); color: var(--ui-accent-ink); }
.nav-item.is-active .nav-item__dot--sync { box-shadow: 0 0 0 2px rgba(255,255,255,.5); }
.nav-item svg { width: 17px; height: 17px; flex: 0 0 17px; }
.nav-item__label { flex: 1; }
.nav-badge {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--orange); color: #fff; font-size: 11px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
}
.nav-item__dot--sync { width: 6px; height: 6px; border-radius: 50%; background: var(--gray); }
.nav-item__dot--sync[data-state="ok"] { background: var(--green); }
.nav-item__dot--sync[data-state="warn"] { background: var(--orange); }
.nav-item__dot--sync[data-state="off"] { background: var(--gray); }

.content {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  min-width: 0;                  /* lets wide tables scroll instead of pushing the layout */
  padding: var(--space-5) var(--space-6);
  padding-right: max(var(--space-6), env(safe-area-inset-right));
}

/* --- Page scaffolding ------------------------------------------------------ */
.page-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-5); }
.page-title { font-size: 22px; font-weight: 600; letter-spacing: -.01em; }
.page-subtitle { font-size: 13px; color: var(--text-2); margin-top: 2px; }

.panel {
  background: var(--panel);
  backdrop-filter: var(--panel-blur, none);
  -webkit-backdrop-filter: var(--panel-blur, none);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--space-5);
}
.panel + .panel { margin-top: var(--space-4); }

/* --- Bottom tab bar (mobile only) ----------------------------------------- */
.tabbar { display: none; }

@media (max-width: 860px) {
  .sidebar { display: none; }
  .content {
    padding: var(--space-4);
    padding-bottom: calc(72px + env(safe-area-inset-bottom));
  }
  .titlebar {
    height: calc(56px + env(safe-area-inset-top));
    flex: 0 0 calc(56px + env(safe-area-inset-top));
  }
  /* Page headers stack instead of clipping their controls off-screen. */
  .page-head { flex-wrap: wrap; }
  .head-actions { flex-wrap: wrap; width: 100%; }
  .segmented { flex-wrap: wrap; }

  .tabbar {
    display: flex;
    position: fixed; left: 0; right: 0; bottom: 0;
    height: calc(60px + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    background: var(--sidebar);
    backdrop-filter: var(--panel-blur, none);
    -webkit-backdrop-filter: var(--panel-blur, none);
    border-top: 1px solid var(--panel-border);
    z-index: 40;
    /* 10 destinations can't share 393px and stay legible (39px each turns every
       label into an ellipsis). Tabs keep a readable width and the bar scrolls,
       with scroll-snap so it lands on whole tabs. */
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
    /* The content runs ~230px past the edge, and nothing said so: the last tab
       was sliced down the middle and read as a rendering fault rather than as
       "there is more this way". The mask fades the final stretch so the cut is
       obviously an edge. It sits on the fixed box, not on the scrolling
       content, so it stays put while the tabs move under it. */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
  }
  .tabbar::-webkit-scrollbar { display: none; }
  /* Scrolled to the end there is nothing more to promise, so the fade goes. */
  .tabbar.is-at-end {
    -webkit-mask-image: none;
    mask-image: none;
  }
  .tabbar__item {
    flex: 0 0 auto;
    min-width: 62px; min-height: 44px;
    scroll-snap-align: center;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px; padding: 6px 6px; color: var(--text-2); font-size: 10px; font-weight: 500;
    position: relative;
  }
  .tabbar__item span {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .tabbar__item.is-active { color: var(--ui-accent); }
  .tabbar__item svg { width: 21px; height: 21px; flex: 0 0 21px; }
  .tabbar__item .nav-badge {
    position: absolute; top: 4px; right: 12px;
    min-width: 15px; height: 15px; font-size: 10px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
