@layer components {
/* ── panes ──────────────────────────────────────────────────────── */
/* The five levels' sheets in one scroll, day on top, life at the foot.
   They lie on a desk, so the parting is a strip of desk and the edge
   that casts onto it, not a rule. A narrow screen spends no width on
   the desk: the band alone parts the sheets. stack.js holds the current
   sheet in place by hand, so the browser's own anchoring stays out. */
#panes {
  --padt: 0px;                                    /* the desk above the first sheet */
  flex: 1; overflow-y: auto; overscroll-behavior: contain; overflow-anchor: none;
  display: flex; flex-direction: column; gap: .3rem; background: var(--desk);
  isolation: isolate;                             /* the rows' own layers stay under the toast */
}
/* a pane's head rides over its own rows for --stickrun (sticky.js) from
   when its row reaches the top of the stack */
@keyframes stick { to { translate: 0 var(--stickrun); } }
} /* @layer components */

@property --stickrun { syntax: '<length>'; inherits: false; initial-value: 0px; }

/* Per element and never inherited: the width of the totals text the
   hour scale fades out under. */
@property --totw { syntax: '<length>'; inherits: false; initial-value: 0px; }

@layer components {
.pane {
  position: relative;                             /* the hover connector anchors here */
  background: var(--bg); flex: none;
  /* the edge over the desk below it */
  box-shadow: 0 3px 5px color-mix(in oklab, var(--shade) 9%, transparent);

  /* nothing written in the span yet: the name and a + to start it */
  &.bare {
    :is(.panehead, .doc, .ghosts) { display: none; }
    .sheettab { display: flex; }
  }
  &:not(.bare) .sheetnew { display: none; }
  .sheettab {
    display: none; align-items: baseline; gap: .5rem;
    padding: .35rem .55rem; font-size: .78rem; color: var(--dim);
  }
  .sheetnew {
    font: inherit; font-size: .8rem; background: none; color: var(--dim);
    border: 1px solid var(--line); border-radius: calc(.8rem * var(--round)); padding: 0 .55rem;
  }

  /* the totals bar and the clock strip travel together, held over the
     rows as one header: the row owns the sideways scroll, so the browser
     cannot pin this to the stack's. Its timeline is the row's, levelrow.css. */
  .panehead {
    position: relative; z-index: 4; background: var(--bg);
    animation: stick linear both; animation-timeline: --row;
    animation-range: exit-crossing 0% exit-crossing var(--stickrun);
  }

  .tot {
    position: relative; padding: .15rem .55rem .02rem; font-size: .78rem; color: var(--dim);
    white-space: nowrap; overflow: hidden;

    /* hide the bar only when it holds nothing — neither totals nor an hour scale */
    &:not(:has(*:not(:empty))) { display: none; }
    &.err, .slip { color: var(--warn); }
    .slip { margin-left: .6rem; }
    .totval { position: relative; z-index: 1; padding-right: .3rem; }
    &.narrow .totval::before { content: 'selected  '; white-space: pre; color: var(--accent); }
    /* the hour scale: single digits over the same drawing box as the strip
       (.55rem in, capped wide), so each lands above its place on the bar.
       Subdued monospace. A mask hides whatever sits under the totals text
       (--totw, its measured width) and fades the numbers in over the 1.1rem
       just past it — so the first one to clear the text eases in, never
       half-clipped. panes.js fitAllHours writes --totw. */
    .tlhours {
      position: absolute; top: 0; bottom: 0; left: .55rem; width: calc(100% - 1.1rem); z-index: 0; pointer-events: none;
      -webkit-mask-image: linear-gradient(90deg, transparent var(--totw), #000 calc(var(--totw) + 1.1rem));
              mask-image: linear-gradient(90deg, transparent var(--totw), #000 calc(var(--totw) + 1.1rem));

      span {
        position: absolute; top: 50%; transform: translate(-50%, -50%);
        font-family: var(--mono);
        font-size: .72rem; color: color-mix(in oklab, var(--ink) 56%, var(--bg)); font-variant-numeric: tabular-nums;
      }
    }
  }
}
.doc { padding: .2rem .55rem .8rem; position: relative; z-index: 1; }
/* A page the caret is not in stops at --cap lines (settings.js; unset,
   it runs). The fade rides the doc's own scroll timeline, which is live
   only while something is cut. */
.pane:not(.open) > .doc {
  max-height: calc(var(--cap) * 1lh); overflow: hidden;
  animation: cut linear both; animation-timeline: scroll(self);
}
@keyframes cut { from, to { mask-image: linear-gradient(#000 calc(100% - 3lh), transparent); } }

/* Room to spare: the sheets pull in off the desk on every side, each
   with its own edge, and the parting grows to a real gap. */
@media (min-width: 700px) {
  #panes { --padt: .7rem; padding: var(--padt) .7rem 2.5rem; gap: .7rem; }
  .pane {
    border: 1px solid var(--line);
    box-shadow: 0 1px 4px color-mix(in oklab, var(--shade) 7%, transparent);

    &.cur { box-shadow: 0 2px 6px color-mix(in oklab, var(--shade) 9%, transparent); }
  }
}

/* On a wide screen the open doc keeps a readable measure rather than
   running the full width. */
@media (min-width: 900px) {
  .pane .doc, .pane .ghosts { max-width: 60rem; }
  /* the strip's drawing box is .55rem in from each edge (its margin); the
     text column is the 60rem .doc less its own .55rem padding pair — so
     cap the strip to 60rem − 1.1rem and the two line up. The hour scale
     shares that drawing box, so it caps the same. */
  .pane .timeline, .pane .tot .tlhours { max-width: calc(60rem - 1.1rem); }
}
} /* @layer components */
