/* layout.css — part 4 of 6 of the app stylesheet.
   Holds: main, the two-column grid, the dismissible side panels, the shell and nav
   rail, and every responsive block.

   ORDER MATTERS. These files were cut out of a single app.css at line boundaries with the
   sequence preserved, so concatenating them in the order index.html links them reproduces the
   original byte for byte — which is what makes the cascade provably unchanged. Equal-specificity
   rules still resolve by source order, so reordering the <link> tags can change rendering.

   The names describe what ended up in each part, not a design: the original file interleaved
   the top bar, layout and per-feature rules, and moving rules to where they belong is a separate
   pass that this split exists to make possible. Palette is in theme.css, linked first. */
    main { max-width: 2560px; margin: 0 auto; padding: 24px clamp(24px, 3vw, 56px); }
    /* One layout everywhere except small screens: a side column (Today above the calendar) beside the
       board. Three columns plus the 210px rail squeezed the board until its own panels overflowed
       sideways at laptop widths. */
    .layout { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 24px; align-items: start; }
    .layout > * { min-width: 0; }   /* grid items must be allowed to shrink or the row overflows */
    /* Dismissible side panels (6.70.0). Each hides on its own; when the last one goes, the column is
       removed and the grid drops to a single track so the board takes the full width. The state lives on
       <body> so one class can reach both the panel and the grid. */
    body.hide-cal .cal-side { display: none; }
    body.hide-report .report-side { display: none; }
    body.no-side .side-col { display: none; }
    body.no-side .layout { grid-template-columns: minmax(0, 1fr); }
    /* In the heading flow, deliberately, not absolutely positioned in the corner. `aside .panel` is not
       a positioned element, so an absolute button would have anchored to the sticky .side-col; and
       .cal-panel is overflow:auto, so it would then have scrolled away from its own heading. */
    .panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
    .panel-head h2 { flex: 1 1 auto; }
    .panel-hide {
      flex: 0 0 auto; margin-left: auto;
      /* 30px: 24 was exactly the WCAG 2.5.8 floor, which is not where a touch target wants to sit. */
      width: 30px; height: 30px; padding: 0; line-height: 1; font-size: 17px;
      display: inline-flex; align-items: center; justify-content: center;
      background: transparent; color: var(--muted);
      border: 1px solid transparent; border-radius: 6px; cursor: pointer;
    }
    .panel-hide:hover { background: var(--panel-2); color: var(--text); border-color: var(--line); }
    .panels-indicator { position: relative; }
    .panels-btn {
      font-size: 13px; padding: 7px 12px; background: var(--panel-2); color: var(--text);
      border: 1px solid var(--line); border-radius: 8px; cursor: pointer;
    }
    .panels-btn:hover { border-color: var(--brand-bright); color: var(--brand); }
    .panels-popover {
      position: absolute; top: calc(100% + 8px); right: 0; z-index: var(--z-header-pop);
      min-width: 210px; padding: 8px; display: flex; flex-direction: column; gap: 2px;
      background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
      box-shadow: var(--shadow);
    }
    .panels-popover[hidden] { display: none; }   /* the class sets display:flex, which beats the UA rule */
    .panels-opt {
      display: flex; align-items: center; gap: 8px; cursor: pointer;
      font-size: 13px; color: var(--text); padding: 6px 8px; border-radius: 8px;
    }
    .panels-opt:hover { background: var(--panel-2); }
    .panels-opt input { accent-color: var(--accent); cursor: pointer; }
    /* Clears the sticky bar. Was a bare `top: 16px`, which parked this behind the header the moment
       the header stopped scrolling away. */
    .side-col { display: flex; flex-direction: column; gap: 24px; position: sticky;
      top: calc(var(--header-h, 0px) + 16px); align-self: start; }
    .layout.signed-out { grid-template-columns: 1fr; }
    /* App shell: left nav rail + content area */
    .shell { display: flex; align-items: flex-start; }
    .shell > main { flex: 1 1 auto; min-width: 0; }
    .railnav {
      /* Same offset as .side-col, and the max-height loses the bar's height too or the
         nav's own scroll area runs off the bottom of the viewport. */
      position: sticky; top: calc(var(--header-h, 0px) + 16px); align-self: flex-start;
      flex: 0 0 210px; width: 210px; box-sizing: border-box;
      margin: 16px 0 16px 16px; max-height: calc(100vh - var(--header-h, 0px) - 32px); overflow-y: auto;
      background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
      display: flex; flex-direction: column; gap: 14px; padding: 14px 10px;
    }
    .rail-group { display: flex; flex-direction: column; gap: 2px; }
    /* Section headers, not links. They previously shared var(--muted) with the nav items directly
       below them, which is why they read as just-another-item: same colour, similar size. Full text
       colour + bold + wide tracking at a smaller size makes the hierarchy unambiguous, and a hairline
       above each subsequent group separates the sections outright. */
    .rail-label {
      font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
      color: var(--text); padding: 2px 10px 5px;
    }
    .rail-group + .rail-group { border-top: 1px solid var(--line); padding-top: 10px; }
    .railnav .scope, .rail-link, .rail-action {
      display: block; width: 100%; box-sizing: border-box; text-align: left;
      background: transparent; border: 0; border-radius: 8px; padding: 8px 10px;
      font: inherit; font-size: 14px; color: var(--muted); cursor: pointer; text-decoration: none;
    }
    .railnav .scope:hover, .rail-link:hover, .rail-action:hover { background: var(--panel-2); color: var(--text); }
    .railnav .scope[hidden], .rail-link[hidden], .rail-action[hidden] { display: none; }
    .railnav .scope.active { background: var(--accent); color: #fff; }
    /* Floated rather than flexed on purpose: turning the rail button into a flex container would
       compete with the `.railnav .scope[hidden]` reassert above (same specificity, order-dependent),
       which is the recurring hidden-attribute gotcha. A float leaves `display` alone. */
    .rail-badge {
      float: right; min-width: 20px; padding: 0 6px; border-radius: 999px;
      background: var(--brand-bright); color: #fff; font-size: 11px; font-weight: 700;
      line-height: 18px; text-align: center; margin-left: 8px;
    }
    .rail-badge[hidden] { display: none; }
    .railnav .scope.active .rail-badge { background: #fff; color: var(--accent); }
    .rail-foot { margin-top: auto; border-top: 1px solid var(--line); padding-top: 10px; display: flex; flex-direction: column; gap: 4px; }
    .rail-foot .theme-toggle { width: 100%; height: auto; justify-content: flex-start; border: 0; border-radius: 8px; padding: 8px 10px; gap: 8px; background: transparent; color: var(--muted); }
    .rail-foot .theme-toggle:hover { background: var(--panel-2); color: var(--text); }
    .rail-foot .theme-toggle::after { content: 'Toggle theme'; font-size: 14px; }
    /* Collapsed by default, and "collapsed" means absent from the flex row — that is what makes the
       content resize into the space instead of the rail floating over it. Desktop only: below 1100px the
       rail is a slide-in drawer whose closed state is translateX(-105%), and display:none there would
       remove the element the transition animates. */
    @media (min-width: 1101px) {
      .railnav:not(.open) { display: none; }
    }
    /* Above the sticky header (130) so the drawer still covers the bar and the dim reaches it, which
       is what happened for free while the header had no z-index at all. */
    .rail-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.4); z-index: var(--z-scrim); }
    /* On large screens give the side columns a little more room and air so the center panel
       doesn't dominate a very wide layout. */
    @media (min-width: 1800px) {
      .layout { grid-template-columns: 360px minmax(0, 1fr); gap: 32px; }
      .side-col { gap: 32px; }
    }
    /* Left calendar + right report are sticky grid items: their grid area spans the
       full (tall) row, so align-self:start keeps them content-height at the top while
       position:sticky pins them in view as the board scrolls. */
    /* The side column is the sticky element now (see .side-col); its children just stack. */
    @media (max-width: 1100px) {
      .layout { grid-template-columns: 1fr; }
      /* Flatten the side column so the three panels order independently: the board stays near the top
         on a phone rather than sitting below both side panels. */
      .side-col { display: contents; }
      .cal-side { order: 1; }
      .board-col { order: 2; }
      .report-side { order: 3; }
      .cal-side, .report-side, .side-col { position: static; }
      .shell { display: block; }
      .railnav {
        position: fixed; top: 0; left: 0; height: 100vh; max-height: none; margin: 0;
        width: 264px; border-radius: 0; border: 0; border-right: 1px solid var(--line);
        z-index: var(--z-drawer); transform: translateX(-105%); transition: transform .2s ease;
      }
      .railnav.open { transform: none; box-shadow: var(--shadow); }
    }
    @media (max-width: 640px) {
      header { padding: 12px 16px; gap: 8px 10px; }
      header h1 { font-size: 17px; line-height: 1.25; }
      /* Drop the action buttons to their own full-width row so the long tenant
         title isn't squeezed into a narrow column beside them. */
      .header-actions { margin-left: 0; flex-basis: 100%; justify-content: flex-start; gap: 8px; flex-wrap: wrap; position: relative; }
      /* Header popovers: on a phone the action buttons sit at the left of a full-width row, so the
         desktop right:0 anchoring flung the popover off the left edge. Pin to the viewport instead;
         --pop-top (set by positionHeaderPopover) places it just under whichever trigger opened it. */
      .cs-popover, .notif-popover, .cl-popover {
        position: fixed; top: var(--pop-top, 96px);
        left: 12px; right: 12px; width: auto; max-width: none;
      }
      main { padding: 16px; }

      /* Card/tree rows: the title and its status pills share one row that won't wrap, so on a
         phone the pills run off the right edge. Give the title the full width and let the pills
         drop onto their own wrapping line beneath it — nothing clips, long titles stay readable. */
      .tnode { flex-wrap: wrap; align-items: flex-start; gap: 4px 8px; }
      .tname { overflow-wrap: anywhere; }
      .tmeta { flex-basis: 100%; flex-wrap: wrap; white-space: normal; padding-left: calc(1em + 4px); }
      /* Reclaim horizontal space eaten by deep nesting. */
      ul.tree { padding-left: 10px; }
      ul.tree ul.tree { margin-left: 4px; }

      /* Same treatment for the flat Active / My Tasks cards. */
      .card { padding: 14px; }
      .card .top { flex-direction: column; gap: 8px; }
      .head-right { flex-direction: row; align-items: center; flex-wrap: wrap; white-space: normal; gap: 6px 8px; }
      .pill { margin-left: 0; }
    }