/* The web app's own styles, over the extension's (newtab.css, copied by the
   build). Everything that looks like the extension comes from there; this
   file adds signing in, touch, and room for a phone's screen. */

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

/* The room for a phone's status bar and notch, kept once: each view starts
   below it on its own, about 20px lower, clear of the soft blur Safari puts
   under the status bar, and nothing else adds to it. A gap at the top of a phone is the thing to watch for here
   (tests/web.test.mjs measures it). */
:root {
  --safe-top: env(safe-area-inset-top, 0px);
}

/* The page runs to the screen's bottom edge, behind the tab bar: on iOS
   "100%" stops short of it (see .screen-fill). */
body {
  height: max(100%, 100lvh);
  padding: 0 env(safe-area-inset-right) 0 env(safe-area-inset-left);
}

/* Room at the bottom of what scrolls, to clear the tab bar (50px tall, 14px
   up) by a little. */
:root {
  /* The tab bar sits as Safari's own toolbar does on an iPhone: 48px tall,
     as far from the screen's bottom and sides as the home indicator's room
     (34px on a phone with Face ID), or 12px where there's none. */
  --tabbar-height: 48px;
  --tabbar-edge: max(env(safe-area-inset-bottom), 12px);
  --tabbar-room: calc(var(--tabbar-edge) + var(--tabbar-height) + 16px);
}

/* The wallpaper and the background image run under the status bar and
   down to the screen's bottom edge. Not fixed in place, as in the
   extension: Safari takes a fixed layer at the top for a header and fills
   the status bar with a flat color instead. And taller than the page: on
   iOS the page stops short of the bottom edge (under Safari's toolbar, or
   the home indicator), and what shows there is the page's own background
   color, so the layers reach the largest the screen can be (100lvh). The
   page itself never scrolls, so they stay put all the same. */
html {
  overflow: hidden;
}

html[data-wallpaper] body::before {
  position: absolute;
  inset: 0 0 auto;
  height: max(100%, 100lvh);
}

/* The page's height on iOS follows what's in it: in the Bookmarks tab, the
   full-height layers above make it the whole screen, and the tab bar sits
   lower. This keeps it that tall in every tab, so the bar doesn't move. */
.screen-fill {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: max(100%, 100lvh);
  visibility: hidden;
  pointer-events: none;
}

.backdrop {
  position: absolute;
  bottom: auto;
  height: calc(max(100%, 100lvh) + var(--backdrop-blur, 0px) * 4);
}

/* The notes scroll under the status bar, which keeps the sheet's own color
   so the text never shows through it. */
body.notes-mode::after {
  position: fixed;
  z-index: 15;
  top: 0;
  right: 0;
  left: 0;
  height: var(--safe-top);
  background: light-dark(#fff, #000);
  content: "";
  pointer-events: none;
}

/* The page runs to the top: the extension keeps room there for the clock
   and search bar, which the notes don't have (the search bar is only on
   the Bookmarks tab). */
#board,
#dock[hidden] + #board,
body.notes-mode .search ~ #dock + #board {
  padding: 0;
}

.notes-mode .notes-page {
  margin-top: 0;
  padding-top: var(--safe-top);
  /* Only the board and stacked goals scroll sideways, never the page, and
     nothing bounces at its ends. */
  overflow-x: hidden;
  overscroll-behavior: none;
}

html,
body {
  overscroll-behavior: none;
}

/* No double-tap zoom, so taps answer at once and scrolls aren't read as
   zooming. */
body {
  touch-action: manipulation;
}

/* The tab bar replaces the extension's switch at the top; what's left there
   is the goals' layout switch, shown with Goals. */
.notes-view-switch {
  display: none;
}

.notes-view-bar {
  position: static;
  margin: 18px 0 0;
  opacity: 1;
  translate: 0;
}

.notes-page:not([data-view="goals"]) .notes-view-bar {
  display: none;
}

/* ---- The tab bar: floating glass at the bottom ---- */

/* Placed from the top of the full-height page (see .screen-fill), not from
   the bottom of iOS's shorter one, so it keeps its distance from the
   screen's real edge. The page never scrolls, so it stays put. */
.tabbar {
  position: absolute;
  z-index: 20;
  top: calc(max(100%, 100lvh) - var(--tabbar-edge) - var(--tabbar-height));
  left: 50%;
  display: flex;
  align-items: center;
  gap: 9px;
  translate: -50% 0;
}

/* On a phone, as wide as Safari's toolbar: the tabs share the width. */
@media (max-width: 700px) {
  .tabbar {
    right: var(--tabbar-edge);
    left: var(--tabbar-edge);
    translate: none;
  }

  .tabbar-views {
    flex: 1;
  }

  .tabbar-tab {
    flex: 1;
  }
}

.signed-out .tabbar {
  display: none;
}

.tabbar-views,
.tabbar-account {
  background: var(--glass-surface);
  box-shadow: var(--glass-rim), var(--glass-shadow);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
}

.tabbar-views {
  display: flex;
  gap: 2px;
  height: var(--tabbar-height);
  padding: 4px;
  border-radius: 999px;
}

.tabbar-tab {
  display: grid;
  place-items: center;
  width: 56px;
  height: calc(var(--tabbar-height) - 8px);
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--muted);
  transition: background-color 160ms ease, color 160ms ease;
}

.tabbar-tab[aria-selected="true"] {
  background: light-dark(rgb(0 0 0 / 0.06), rgb(255 255 255 / 0.13));
  color: var(--fg);
}

.tabbar svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The same line on every icon, whatever its drawing's size. */
.tabbar svg * {
  vector-effect: non-scaling-stroke;
}

.tabbar svg .solid {
  fill: currentColor;
  stroke: none;
}

.tabbar-account {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: var(--tabbar-height);
  height: var(--tabbar-height);
  padding: 0;
  border: 0;
  border-radius: 50%;
  color: var(--fg);
}

/* A dot while sync can't reach the cloud. */
.tabbar-account.sync-problem::after {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff9f0a;
  content: "";
}

.account-menu {
  width: 240px;
}

.menu .menu-chosen::after {
  margin-left: auto;
  padding-left: 12px;
  content: "✓";
}

.menu .menu-chosen {
  display: flex;
}

.signed-out #board {
  visibility: hidden;
}

/* ---- Signing in: a centered pane of glass ---- */

.signin-screen {
  position: fixed;
  z-index: 50;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 24px 16px;
  overflow-y: auto;
  background:
    radial-gradient(90% 60% at 20% 0%, light-dark(rgb(140 160 255 / 0.35), rgb(70 90 200 / 0.35)), transparent 70%),
    radial-gradient(80% 60% at 100% 100%, light-dark(rgb(255 170 210 / 0.35), rgb(160 60 140 / 0.3)), transparent 70%),
    light-dark(#f2f2f7, #000);
}

.signin {
  display: grid;
  gap: 14px;
  width: min(380px, 100%);
  padding: 36px 28px 26px;
  border-radius: var(--glass-radius);
  background: var(--glass-surface);
  box-shadow: var(--glass-rim), var(--glass-shadow);
  -webkit-backdrop-filter: blur(30px) saturate(1.8);
  backdrop-filter: blur(30px) saturate(1.8);
  color: var(--ink);
  text-align: center;
}

.signin-mark {
  justify-self: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: linear-gradient(165deg, #13263f, #231636);
  box-shadow: var(--glass-rim), 0 10px 24px -8px rgb(35 22 54 / 0.6);
}

.signin h1 {
  margin: 4px 0 0;
  font: 600 30px/1.1 "SF Pro Rounded", ui-rounded, -apple-system, system-ui, sans-serif;
  letter-spacing: -0.01em;
}

.signin-lead {
  margin: -6px 0 8px;
  color: var(--ink-muted);
  font-weight: 400;
}

.signin-fields {
  display: grid;
  gap: 8px;
}

.signin .settings-input {
  height: 44px;
  border: 0;
  border-radius: 12px;
  background: light-dark(rgb(255 255 255 / 0.8), rgb(255 255 255 / 0.08));
  box-shadow: inset 0 0 0 1px light-dark(rgb(0 0 0 / 0.08), rgb(255 255 255 / 0.1));
  /* 16px or more, or Safari zooms in on focus. */
  font-size: 16px;
  font-weight: 400;
}

.signin-note {
  min-height: 1.2em;
  margin: 0;
  color: var(--ink-muted);
  font-weight: 400;
}

.signin-note:empty {
  display: none;
}

.signin-submit {
  height: 46px;
  border: 0;
  border-radius: 14px;
  background: linear-gradient(165deg, #13263f, #231636);
  box-shadow: var(--glass-rim);
  color: #fff;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
}

.signin-submit:disabled {
  opacity: 0.6;
}

.signin-links {
  display: flex;
  justify-content: center;
  gap: 4px;
}

.signin-link {
  padding: 8px 10px;
  border: 0;
  background: none;
  color: var(--selection);
  font: inherit;
}

/* ---- Touch: holding to drag or for a menu (touch.js) ---- */

@media (hover: none) {
  [draggable="true"],
  .kanban-project-head,
  .goals-area-head,
  .goals-period-head {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }
}

.touch-lifted {
  transform: scale(1.03);
  transition: transform 0.15s;
}

.touch-ghost {
  position: fixed;
  z-index: 100;
  margin: 0;
  opacity: 0.94;
  box-shadow: 0 18px 40px -12px rgb(0 0 0 / 0.35);
  pointer-events: none;
}

.touch-dragging,
.touch-dragging * {
  -webkit-user-select: none;
  user-select: none;
}

/* ---- No pointer to hover with: what hover reveals stays shown ---- */

@media (hover: none) {
  /* New task and New goal: a row at the end of the list, like Notion's
     "+ New", rather than a pill shown on hover over its edge. */
  .kanban .kanban-lane > .kanban-add,
  .goals .goals-period > .kanban-add {
    position: static;
    display: flex;
    width: 100%;
    min-height: 40px;
    margin-top: 4px;
    padding: 0 8px;
    border-radius: 10px;
    background: none;
    box-shadow: none;
    color: var(--muted);
    font-size: 14px;
    opacity: 1;
    translate: none;
  }

  .kanban .kanban-lane > .kanban-add svg,
  .goals .goals-period > .kanban-add svg {
    width: 14px;
    height: 14px;
  }

  .kanban .kanban-lane {
    padding-bottom: 4px;
  }

  .kanban .kanban-project > .kanban-project-head svg,
  .kanban > .kanban-add-project,
  .goals .goals-area-head svg,
  .goals > .kanban-add-project,
  .goals-stats {
    opacity: 1;
    translate: 0;
  }

  /* A card without a date keeps its calendar button out of the way: the
     card's menu sets one. */
  .kanban-card .kanban-due.empty {
    display: none;
  }
}

/* ---- A phone: one column at a time, swiped like Notion's boards ---- */

@media (max-width: 700px) {
  .notes-sheet {
    padding: 22px 22px 40vh;
  }

  .goals-minimap-host {
    display: none;
  }

  /* The board: each stage nearly as wide as the screen, the next one
     peeking in, snapping to each as it's swiped. Project names stay put. */
  .kanban {
    --kanban-columns: repeat(4, calc(100vw - 64px));
    width: 100%;
    padding: 18px 20px var(--tabbar-room);
    overscroll-behavior: none;
  }

  /* Down to the screen's bottom however few cards, so a swipe anywhere
     below them still moves the stages. */
  .kanban,
  .goals[data-layout="rows"] {
    flex: 1 0 auto;
  }

  /* A project's name is as wide as the screen, all of it a target for
     folding, and stays put as the stages scroll. */
  .kanban .kanban-project-head {
    position: sticky;
    left: 0;
    width: calc(100vw - 40px);
    min-height: 44px;
    margin-left: 0;
  }

  /* An area's name is as wide as its column, all of it a target. */
  .goals-area-head {
    width: 100%;
    min-height: 44px;
  }

  /* Goals: one area under another, Currently above Yearly. */
  .goals,
  .goals[data-layout="columns"] {
    width: 100%;
    padding: 4px 20px var(--tabbar-room);
  }

  .goals-periods,
  .goals[data-layout="columns"] .goals-periods {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked: each area a column nearly as wide as the screen, swiped. */
  .goals[data-layout="rows"] {
    padding: 4px 20px var(--tabbar-room);
    overscroll-behavior: none;
    mask-image: none;
  }

  .goals[data-layout="rows"] .goals-area,
  .goals[data-layout="rows"] .goals-area:first-child {
    width: calc(100vw - 64px);
  }

  .goals[data-layout="rows"] .goals-area-head {
    margin-left: 0;
  }
}

/* On a phone's touch screen, pager.js moves the stages and stacked areas
   sideways, a stage at a time and one direction per swipe; the phone's own
   sideways scrolling would let a swipe move the page both ways at once. */
@media (max-width: 700px) and (hover: none) {
  .kanban,
  .goals[data-layout="rows"] {
    overflow-x: hidden;
  }
}

/* ---- The Bookmarks tab (bookmarks-tab.js): the page as the new tab page
   shows its bookmarks, with room for the tab bar ---- */

.bookmarks-view #board {
  padding: 24px 24px var(--tabbar-room);
}

.bookmarks-view .search {
  margin-top: calc(var(--safe-top) + 32px);
}

/* The extension steps the columns down under a "Folders" title, which the
   web app doesn't have. */
html:not(.panel) .bookmarks-view #board > .column:not(.side) {
  margin-top: 0;
}

.bookmarks-empty {
  max-width: 420px;
  margin: auto;
  color: var(--fg);
  font-weight: 400;
  line-height: 1.45;
  text-align: center;
}

.bookmarks-empty-title {
  font-size: 19px;
  font-weight: 600;
}

.screen-sizes {
  font: 500 11px/1.4 ui-monospace, Menlo, monospace;
  white-space: pre-line;
}

/* The pills keep to two rows (bookmarks-tab.js), so the extension's own
   scrolling in them goes. */
.bookmarks-view #dock {
  max-height: none;
  overflow: visible;
}

.pill-more {
  justify-content: center;
  width: 50px;
  padding: 0;
  border: 0;
  font: inherit;
}

.pill-more svg {
  flex: none;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pills-more .pill-more svg {
  rotate: 180deg;
}

/* All the pills, over the columns, opened by See More. */
.pills-scrim {
  position: fixed;
  z-index: 24;
  inset: 0;
}

.pills-more {
  position: fixed;
  z-index: 25;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 10px;
  align-content: flex-start;
  justify-content: center;
  padding: 14px 12px;
  overflow-y: auto;
  border-radius: 32px;
  background: var(--glass-surface);
  box-shadow: var(--glass-rim), var(--glass-shadow);
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  backdrop-filter: blur(30px) saturate(180%);
  overscroll-behavior: contain;
  scrollbar-width: none;
  animation: pills-more-in 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

@keyframes pills-more-in {
  from {
    opacity: 0;
    translate: 0 -8px;
    scale: 0.98;
  }
}

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

/* chrome:// pages and bookmarklets open only in Chrome. */
.unopenable {
  opacity: 0.55;
  cursor: default;
}

@media (max-width: 700px) {
  /* A column at a time, nearly as wide as the screen, swiped (pager.js). */
  .bookmarks-view #board {
    --column-width: calc(100vw - 48px);
    gap: 12px;
    padding: 12px 24px var(--tabbar-room);
  }

  .bookmarks-view .search {
    width: calc(100% - 48px);
    margin-top: calc(var(--safe-top) + 12px);
  }

  /* The pills in up to two rows; more scroll within them. */
  .bookmarks-view #dock {
    width: 100%;
    min-height: 0;
    margin-top: 6px;
    padding: 8px 24px;
  }

  .bookmarks-view #dock .pill {
    max-width: calc(100vw - 48px);
  }
}

@media (max-width: 700px) and (hover: none) {
  .bookmarks-view #board {
    overflow-x: hidden;
  }
}
