/* Content Calendar, the HOVER-FREE SWEEP (P3-6, 2026-08-19).
 *
 * A phone has no hover. Every affordance in the CC cards that is only carried
 * by :hover is therefore invisible or unreachable on the device the mobile
 * spec is written for. This file is the counterpart layer: every :hover in the
 * CC card CSS gets an @media (hover: none) answer, and the shared anchored
 * popup becomes a bottom sheet below 760px.
 *
 * It adds no new class names. It only answers rules that already exist, so a
 * card can be restyled without coming back here.
 *
 * -- THIS FILE MUST BE LINKED, AND NOTHING FAILS LOUDLY IF IT IS NOT ---------
 * It is a stylesheet, so an unlinked file produces no console error, no 404 in
 * a place anyone looks and no visible breakage on a desktop. It produces a
 * phone where every control is silent under the finger and the .dd-popup is
 * still a 280px box anchored over the cell it describes. The build plan's
 * wiring step lists four stylesheets for the new <link> block
 * (dd-focus-points-card.css, dd-mobile.css, cc-schedule.css,
 * cc-connect-wizard.css). This is a FIFTH, and it must be added:
 *
 *   <link rel="stylesheet" href="pages/deliverable-dashboard/dd-mobile-hover-free.css">
 *
 * placed AFTER dd-mobile.css, because several rules here answer a base rule at
 * equal specificity and win only on source order.
 *
 * dd-mobile.css:882-886 says the per-control sweep is appended inside its own
 * @media (hover: none) block. It is not. It lives here, in a separate file, so
 * the sweep can be reviewed and reverted on its own. Read that comment as
 * pointing at this file.
 *
 * -- THE ENUMERATION ---------------------------------------------------------
 * Grepped: deliverable-dashboard.css (132 :hover rules), dd-focus-points-card.css,
 * cc-schedule.css, cc-connect-wizard.css, and the styles injected at runtime by
 * cc-post-popup.js, dd-cc-approval-controls.js, dd-focus-point-pop.js and
 * dd-sheet.js.
 *
 * A. NOTHING IN THE CC CARDS IS DISPLAY-HIDDEN UNTIL HOVER. Not one rule in
 *    this surface sets opacity: 0 or display: none and lifts it on :hover. The
 *    hover-reveal pattern does exist in this app (.col-reveal in
 *    collateral.css:280, .prod-status-chain-edit in production-page.css:2470,
 *    .prod-row-left-actions in production-page.css:438) and the first two
 *    already carry their own @media (hover: none) answer. The CC cards were
 *    written after that lesson: dd-focus-points-card.js:667 says so in a
 *    comment and renders the row insert button unconditionally. So there is no
 *    hidden control to un-hide here, and this file must not invent one.
 *
 * B. HOVER IS THE ONLY SIGNAL THAT SOMETHING IS PRESSABLE. This is the real
 *    hole. These controls look like plain surface until a pointer lands on
 *    them, and on touch that never happens, so they get an :active answer that
 *    fires on the press instead:
 *      .ccs-tab                     cc-schedule.css:183
 *      .ccs-postcell                cc-schedule.css:264
 *      .ccw-press, .ccw-ghost       cc-connect-wizard.css:202, :218
 *      .dd-btn and its variants     deliverable-dashboard.css:227-232, :737-739
 *      .dd-back-btn                 deliverable-dashboard.css:102
 *      .dd-date-btn                 deliverable-dashboard.css:291
 *      .dd-cap-tool                 deliverable-dashboard.css:317
 *      .dd-emoji-pop button         deliverable-dashboard.css:373
 *      .dd-media-header             deliverable-dashboard.css:400
 *      .dd-media-chip               deliverable-dashboard.css:431
 *      .dd-media-chip-dead          deliverable-dashboard.css:451
 *      .dd-media-chip-x             deliverable-dashboard.css:446
 *      .dd-media-thumb-clickable    deliverable-dashboard.css:460
 *      .dd-img-lightbox-x           deliverable-dashboard.css:2037
 *      .dd-media-upload             deliverable-dashboard.css:468
 *      .dd-media-vidbtn             deliverable-dashboard.css:477
 *      .dd-cr-addbtn                deliverable-dashboard.css:516
 *      .dd-cr-shot-thumb            deliverable-dashboard.css:2033
 *      .dd-popup-x                  deliverable-dashboard.css:600
 *      .dd-wd-del                   deliverable-dashboard.css:691
 *      .dd-team-member              deliverable-dashboard.css:155
 *      .dd-team-add                 deliverable-dashboard.css:171
 *      .dd-team-del                 deliverable-dashboard.css:1471
 *      .dd-fp-btn                   injected, dd-focus-point-pop.js:130
 *      .dd-sheet-item, .dd-sheet-x  injected, dd-sheet.js:153, :138
 *      .dd-sheet-btn and variants   injected, dd-sheet.js:170, :174, :176
 *      .cc-pp-x                     injected, cc-post-popup.js:268
 *      .cc-pp-btn and variants      injected, cc-post-popup.js:332, :336, :338
 *
 * C. LINKS THAT ONLY UNDERLINE ON HOVER. Blue text with no underline reads as
 *    a label, not a link, and on touch it never gets the underline that would
 *    have told the truth. Underlined permanently below the hover cut:
 *      .ccfp-link-url               dd-focus-points-card.css:72
 *      .ccs-live                    cc-schedule.css:321
 *      .dd-info-value a             deliverable-dashboard.css:201
 *      .dd-media-chip .dd-media-name a   deliverable-dashboard.css:441
 *      .dd-wd-openlink              deliverable-dashboard.css:675
 *      .dd-focus-filelink           deliverable-dashboard.css:781
 *      .dd-banner-link-url          deliverable-dashboard.css:1583
 *
 * D. AN AFFORDANCE THAT IS A LIE ON TOUCH. .ccfp-handle
 *    (dd-focus-points-card.css:139) is cursor: grab and lights up on hover,
 *    but it drives HTML5 drag and drop, which does not fire from a touch
 *    pointer at all. Below the hover cut it is demoted to a static row marker:
 *    no grab cursor, no pressed state, no hover paint. Reordering on touch is
 *    the Move control in dd-move-mode.js (P3-4), not this grip. This file does
 *    NOT hide the grip, because P3-4 owns what replaces it and hiding it from
 *    here would fight that task.
 *
 * E. TITLE ATTRIBUTES ARE HOVER-ONLY AND CSS CANNOT FIX THEM. A native tooltip
 *    needs a hovering pointer. Thirteen title= strings across the CC cards
 *    never appear on a phone, and where the title is the ONLY explanation the
 *    information is simply gone. CSS could print them with content: attr(title)
 *    but that would be worse, not better: the grip's title reads "Drag to
 *    reorder" and on touch dragging is exactly what does not work. These need a
 *    visible label or a sheet from the owning JS file, and are listed here so
 *    the owner sees them rather than being quietly papered over:
 *      dd-focus-points-card.js:585  "The client has approved this plan, it can
 *                                    no longer be reordered", the only place
 *                                    the frozen state is explained
 *      dd-focus-points-card.js:586  "Drag to reorder, the date moves with the row"
 *      dd-focus-points-card.js:671  "Insert a focus point below this one", which
 *                                    has an aria-label so a screen reader is
 *                                    fine and a sighted touch user is not
 *      dd-focus-points-card.js:679  "Remove this focus point"
 *      cc-schedule-card.js          the tab reason, note and count label
 *      cc-schedule-card.js          "Disabled: <why>" on a blocked action, the
 *                                    only place the refusal reason is written
 *      dd-cc-approval-controls.js   "Show this client's approval link" and the
 *                                    no-token message
 *
 * F. .dd-posts-table tbody tr:hover (deliverable-dashboard.css:256) needs no
 *    answer. Below 760px the table already stacks into bordered cards
 *    (deliverable-dashboard.css:524-545), so each row is separated by its own
 *    border and the hover tint has nothing left to do.
 *
 * -- THE FOCUS POINT TRIGGER CONTRACT ----------------------------------------
 * window.ddFocusPointPop already meets this. It is written down here because
 * the next read-only detail pop that gets built will be copied from it, and the
 * copy is where the mobile behaviour usually gets dropped.
 *
 *   1. The trigger is a real <button type="button"> carrying aria-expanded, not
 *      a span with a mouseenter listener. Class .dd-fp-btn, min-height 44px.
 *   2. It opens on pointerenter AND on keyboard focus AND on click or tap. A
 *      hover-only opener is unreachable on a phone, a click-only opener is slow
 *      on a desktop, so it answers all three.
 *   3. It is labelled with words, "Focus point", never a bare (i). An
 *      unlabelled icon above a caption box reads as a form hint, not as
 *      something you can press.
 *   4. Below 760px it does not position an anchored box. It hands off to
 *      window.ddSheet.info, because the cell it describes is full width there
 *      and an anchored box would cover exactly the thing being explained.
 *   5. Its hover paint has an :active twin, below, so the press is acknowledged
 *      on a device that cannot hover.
 *   6. It renders nothing at all when its resolver is empty. An always-present
 *      trigger that pops "nothing here" is twelve rows of noise on a month.
 *
 * -- THE .dd-popup TO SHEET CONVERSION ---------------------------------------
 * openPopup (deliverable-dashboard.js:6557) anchors a 280px card under the
 * control that opened it. Below 760px that control sits inside a full width
 * stacked cell, so an anchored 280px box lands mid-column over the very cell it
 * is describing, and its internal max-height is computed against a viewport the
 * on-screen keyboard is about to halve. Below 760px it becomes a bottom sheet
 * instead, in the same visual grammar as window.ddSheet: full width, radius
 * 16px 16px 0 0, capped at 80vh, its own scroll, a grab pill at the top.
 *
 * Two things this conversion is honest about:
 *
 *   1. IT IS PRESENTATION ONLY. It does not give the popup ddSheet's focus
 *      trap, body lock or backdrop, because those are JS and openPopup lives in
 *      a main-thread file this task does not own. The popup keeps its own
 *      capture-phase Esc and outside-mousedown close
 *      (deliverable-dashboard.js:6554-6555), which a tap does fire. A real
 *      window.ddSheet handoff is a change inside openPopup and belongs to
 *      whoever owns deliverable-dashboard.js.
 *   2. IT NEEDS !important. openPopup writes top, left and maxHeight as inline
 *      styles after measuring, so a plain rule loses to the style attribute
 *      every time. Only the three properties it actually sets are forced.
 *
 * -- WHY SOME RULES CARRY !important AND MOST DO NOT -------------------------
 * dd-focus-point-pop.js, dd-sheet.js, cc-post-popup.js and
 * dd-cc-approval-controls.js inject their stylesheets into <head> on first
 * open, which is AFTER this file's <link>. At equal specificity the later sheet
 * wins, so answers to a JS-injected rule are forced. Answers to a rule that
 * lives in a real .css file are not, because this file loads after those and
 * plain source order is enough. Do not tidy this up by making them uniform in
 * either direction.
 *
 * Load order: after deliverable-dashboard.css, dd-focus-points-card.css,
 * cc-schedule.css, cc-connect-wizard.css and dd-mobile.css.
 */

/* ===========================================================================
   B. PRESSED STATE FOR EVERY CONTROL WHOSE ONLY FEEDBACK WAS :hover
   Scoped to (hover: none) so a mouse keeps the hover paint it already has, and
   a laptop with a touchscreen, which reports (hover: hover), is untouched.
   =========================================================================== */
@media (hover: none) {
  .ccs-tab:active { background: #f3f4f6; }
  .ccs-postcell:active { background: #e5e7eb; }

  .ccw-press:active:not(:disabled) { box-shadow: 3px 3px 0 var(--ccw-accent); transform: translate(-1px, -1px); }
  .ccw-ghost:active { border-color: var(--ccw-ink); color: var(--ccw-ink); }

  .dd-btn:active { background: #f3f4f6; border-color: #c7d2fe; }
  .dd-btn-primary:active { background: #1d4ed8; border-color: #1d4ed8; }
  .dd-btn-danger:active { background: #fef2f2; border-color: #fca5a5; }
  .dd-btn-complete:active { background: #15803d; border-color: #15803d; }
  .dd-btn-undo:active { background: #f3f4f6; border-color: #d1d5db; }
  .dd-back-btn:active { background: #f3f4f6; border-color: #d1d5db; }

  .dd-date-btn:active { border-color: #93c5fd; background: #f8faff; }
  .dd-cap-tool:active { background: #fff; border-color: #e5e7eb; color: #1d4ed8; }
  .dd-emoji-pop button:active { background: #f3f4f6; }

  .dd-media-header:active { background: #f1f5f9; }
  .dd-media-chip:active { border-color: #cbd5e1; }
  /* The dead chip is amber, not slate, so its press keeps its own colour.
     Without this a healthy chip acknowledges the finger and a broken one does
     not, which reads as the broken one being unpressable. */
  .dd-media-chip-dead:active { border-color: #f59e0b; }
  .dd-media-chip-x:active { color: #b91c1c; }
  .dd-media-thumb-clickable:active { filter: brightness(.92); border-color: #93c5fd; }
  /* The exit of the lightbox that thumb opens. It sits over a dimmed photo with
     no border of its own, so the press is the only thing that says it took. */
  .dd-img-lightbox-x:active { background: rgba(255, 255, 255, .3); }
  .dd-media-upload:active,
  .dd-media-vidbtn:active { border-color: #93c5fd; color: #1d4ed8; background: #f8faff; }

  .dd-cr-addbtn:active { border-color: #93c5fd; color: #1d4ed8; background: #f8faff; }
  .dd-cr-shot-thumb:active { border-color: #93c5fd; }
  .dd-popup-x:active { color: #374151; }
  .dd-wd-del:active { color: #b91c1c; }

  /* The Team card. Plan step 34 wraps it in ddCollapse on every CC dashboard,
     so on a phone these three are the whole of that card's interaction. */
  .dd-team-member:active { border-color: #c7d2fe; box-shadow: 0 1px 4px rgba(0, 0, 0, .06); }
  .dd-team-add:active { border-color: #a5b4fc; background: #f5f6ff; box-shadow: none; }
  .dd-team-del:active { color: #b91c1c; }

  .ccfp-insert:active { background: #f3f4f6; border-color: #c7d2fe; }
  .ccfp-del:active { background: #fef2f2; border-color: #fca5a5; }

  /* Injected stylesheets, so forced. See the header note on !important. */
  .dd-fp-btn:active { background: #eef2ff !important; border-color: #c7d2fe !important; color: #4338ca !important; }
  .dd-sheet-item:active { background: #f9fafb !important; border-color: #d1d5db !important; }
  .dd-sheet-x:active { background: #f3f4f6 !important; color: #374151 !important; }
  /* The sheet footer is where every confirm in the mobile design lands, the
     Move mode confirm included, so its normal and primary buttons need the
     press as much as the danger one already had it. */
  .dd-sheet-btn:active { background: #f3f4f6 !important; }
  .dd-sheet-btn.is-primary:active { background: #1d4ed8 !important; }
  .dd-sheet-btn.is-danger:active { background: #b91c1c !important; }

  /* The per-post editor on the Schedule card. Same injected-sheet problem. */
  .cc-pp-x:active { background: #f3f4f6 !important; color: #374151 !important; }
  .cc-pp-btn:active { background: #f3f4f6 !important; }
  .cc-pp-btn.is-primary:active { background: #1d4ed8 !important; }
  .cc-pp-btn.is-danger:active { background: #fef2f2 !important; }

  /* -- THE TWO PHONE-ONLY INJECTED SHEETS ------------------------------------
     The enumeration at the top of this file lists four injected stylesheets and
     misses these two, because both belong to modules that only ever paint below
     the mobile cut, so a desktop grep for the surface never reaches them:

       dd-mobile-bar.js:132   #dd-mobile-bar-styles, the whole sheet wrapped in
                              @media (max-width:760px). Interactive selectors it
                              declares: .dd-mobile-bar-btn, .dd-mobile-bar-primary,
                              .dd-mobile-bar-primary.is-danger and the dark twin
                              of the first. Every one carried :hover and none
                              carried :active.
       dd-needs-work.js:194   #dd-needs-work-styles. One interactive selector,
                              .dd-nw-chip, with :hover and no :active. It has no
                              dark rules of its own, so none are answered here.

     This is the worst place for the hole to be, not the mildest: the bar is the
     primary action on every CC dashboard on a phone and the chip is the only way
     back out of a filtered list. Both are phone-only, so :hover is the one paint
     that can never fire for the pointer they were built for, and a hover that a
     touch browser DOES emulate then sticks after the finger lifts, which leaves
     the last button tapped looking permanently held.

     Forced, because both sheets are appended to <head> on first mount, long
     after this file's <link>. Neither injected rule carries !important, so a
     single !important here settles it whatever the specificity.

     A touch browser that emulates hover has BOTH states set while the finger is
     down, so each neutralisation is paired with a press rule that outranks it.
     The pairing is plain specificity and source order, neutralisation first,
     press second. An earlier draft guarded the neutralisations with :not(:active)
     instead, and a forced-state check in Chromium showed the bar primary keeping
     its neutralised blue through the press, so the guard was not doing the job it
     looked like it was doing. Specificity and order are unambiguous, so that is
     what this leans on: every press rule below is at least as specific as every
     hover rule that can match the same element, and comes after it. */
  .dd-mobile-bar-btn:hover { background: #fff !important; }
  .dd-mobile-bar-primary:hover { background: #2563eb !important; }
  .dd-mobile-bar-primary.is-danger:hover { background: #dc2626 !important; }
  /* The dark hover paint is scoped off the primary, which the injected rule is
     not. Theirs is .dd-mobile-bar-btn:hover, so in dark it also repaints the
     blue primary slate on hover, and neutralising with the same reach would
     leave the primary grey under a finger. */
  html[data-theme="dark"] .dd-mobile-bar-btn:not(.dd-mobile-bar-primary):hover { background: #111827 !important; }
  /* A pressed chip is excluded, so neutralising the hover cannot strip the
     indigo that says the filter is on. */
  .dd-nw-chip:hover:not([aria-pressed="true"]) { border-color: #e5e7eb !important; color: #4b5563 !important; }

  .dd-mobile-bar-btn:active { background: #f3f4f6 !important; }
  html[data-theme="dark"] .dd-mobile-bar-btn:not(.dd-mobile-bar-primary):active { background: #151f2e !important; }
  .dd-mobile-bar-primary:active { background: #1d4ed8 !important; }
  .dd-mobile-bar-primary.is-danger:active { background: #b91c1c !important; }
  /* :not([disabled]) is what lifts this over the hover rule above it, and it is
     honest on its own terms: a disabled chip should not answer the finger. */
  .dd-nw-chip:active:not([disabled]) { border-color: #c7d2fe !important; color: #4338ca !important; }

  /* dd-move-mode.js:101 is a third phone-only injected sheet. It declares no
     :hover at all, so it has no hover paint to neutralise, and .dd-move-bar-btn
     already answers the press itself. Its two other controls did not, and a Move
     control that stays silent under the finger is the same defect as the bar's.
     .dd-move-btn keeps its own pressed-open background, so only the idle press
     is painted here. */
  .dd-move-btn:active:not([aria-pressed="true"]) { background: #eff6ff !important; border-color: #93c5fd !important; }
  .dd-move-strip-btn:active:not([disabled]) { background: #eff6ff !important; }
  .dd-move-strip-done:active:not([disabled]) { background: #1e40af !important; }
}

/* ===========================================================================
   C. LINKS CARRY THEIR UNDERLINE PERMANENTLY WHERE THERE IS NO HOVER
   =========================================================================== */
@media (hover: none) {
  .ccfp-link-url,
  .ccs-live,
  .dd-info-value a,
  .dd-media-chip .dd-media-name a,
  .dd-wd-openlink,
  .dd-focus-filelink,
  .dd-banner-link-url { text-decoration: underline; }
}

/* ===========================================================================
   D. THE FOCUS POINT GRIP IS A MARKER, NOT A CONTROL, ON TOUCH
   Native drag and drop does not fire from a touch pointer, so nothing here may
   suggest it will. Reordering on touch is the Move control in P3-4.
   =========================================================================== */
@media (hover: none) {
  .ccfp-handle { cursor: default; }
  .ccfp-handle:active { cursor: default; background: transparent; color: #9ca3af; }
  .ccfp-handle.is-static:active { background: transparent; color: #d1d5db; }
}

/* ===========================================================================
   THE ANCHORED POPUP BECOMES A BOTTOM SHEET BELOW 760px
   Keyed on width, not on (hover: none), because the reason is the stacked
   layout rather than the pointer: a narrow window on a desktop has the same
   full width cell and the same wrong-place popup.
   =========================================================================== */
@media (max-width: 760px) {
  .dd-popup {
    /* top, left and max-height are inline styles written by openPopup. */
    position: fixed !important;
    top: auto !important;
    left: 0 !important;
    max-height: 80vh !important;
    right: 0;
    bottom: 0;
    width: 100%;
    max-width: 100%;
    border: none;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -12px 40px rgba(15, 23, 42, .28);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  /* The ddSheet grab pill, so a converted popup reads as the same component.
     Decorative only: the close X in the head stays the accessible control, the
     same split dd-sheet.js:128 makes. .dd-popup is a column flex container
     (deliverable-dashboard.css:2040) so this is a flex item, hence flex: 0 0 auto. */
  .dd-popup::before {
    content: '';
    flex: 0 0 auto;
    align-self: center;
    width: 40px;
    height: 4px;
    margin: 10px 0 6px;
    border-radius: 2px;
    background: #d1d5db;
  }

  /* Head pinned, body owns the scroll. Without min-height: 0 a long body
     refuses to shrink inside the flex column and pushes past the 80vh cap. */
  .dd-popup-head {
    flex: 0 0 auto;
    padding: 8px 14px 12px;
    background: transparent;
    border-bottom: 1px solid #f1f5f9;
  }
  .dd-popup-title { font-size: 16px; }
  .dd-popup-body {
    flex: 1 1 auto;
    min-height: 0;
    padding: 14px;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  /* 44px close target. The base rule is a bare glyph with 2px of padding, which
     is a 20px tap area sitting in the corner of a full width sheet. */
  .dd-popup-x {
    width: 44px;
    height: 44px;
    margin: -10px -10px 0 0;
    font-size: 24px;
    border-radius: 10px;
  }

  /* iOS zooms the page when a focused input is under 16px, and the zoom does
     not undo itself on blur, which leaves the sheet off screen. */
  .dd-popup-input,
  .dd-popup-ta { font-size: 16px; padding: 11px 12px; }
  .dd-popup-ta { min-height: 96px; }

  /* Buttons inside a converted popup are full width rows, matching the sheet
     footer grammar in dd-sheet.js:165-167. */
  .dd-popup-row { gap: 10px; }
  .dd-popup-row .dd-btn { flex: 1 1 auto; justify-content: center; min-height: 48px; }
}

/* ===========================================================================
   DARK THEME
   Only the surfaces painted above. Everything else inherits the dark rules
   already in deliverable-dashboard.css and dd-focus-points-card.css.
   =========================================================================== */
@media (hover: none) {
  html[data-theme="dark"] .ccs-tab:active { background: #151f2e; }
  html[data-theme="dark"] .ccs-postcell:active { background: #1f2937; }
  html[data-theme="dark"] .dd-btn:active { background: #151f2e; border-color: #334155; }
  html[data-theme="dark"] .dd-btn-undo:active { background: #151f2e; border-color: #334155; }
  html[data-theme="dark"] .dd-media-header:active { background: #151f2e; }
  html[data-theme="dark"] .dd-back-btn:active { background: #334155; border-color: #475569; }
  html[data-theme="dark"] .dd-media-chip:active { border-color: #334155; }
  html[data-theme="dark"] .dd-media-chip-dead:active { border-color: rgba(245, 158, 11, .70); }
  html[data-theme="dark"] .dd-media-chip-x:active { color: #f87171; }
  html[data-theme="dark"] .dd-team-member:active { border-color: rgba(129, 140, 248, .55); box-shadow: 0 1px 4px rgba(0, 0, 0, .35); }
  html[data-theme="dark"] .dd-team-add:active { border-color: #818cf8; background: rgba(99, 102, 241, .18); }
  html[data-theme="dark"] .dd-team-del:active { color: #f87171; }
  html[data-theme="dark"] .dd-popup-x:active { color: #e5e7eb; }
  html[data-theme="dark"] .dd-wd-del:active { color: #f87171; }
  html[data-theme="dark"] .ccfp-handle:active { color: #64748b; background: transparent; }
  html[data-theme="dark"] .ccfp-handle.is-static:active { color: #475569; background: transparent; }
  html[data-theme="dark"] .ccfp-insert:active { background: #151f2e; border-color: #334155; }

  /* Injected stylesheets again. Without these the light press paint above
     would flash a near-white panel over a dark sheet. */
  html[data-theme="dark"] .dd-sheet-btn:active { background: #151f2e !important; }
  html[data-theme="dark"] .cc-pp-x:active { background: #1f2937 !important; color: #e5e7eb !important; }
  html[data-theme="dark"] .cc-pp-btn:active { background: #151f2e !important; }
}

@media (max-width: 760px) {
  html[data-theme="dark"] .dd-popup {
    box-shadow: 0 -12px 40px rgba(0, 0, 0, .6);
  }
  html[data-theme="dark"] .dd-popup::before { background: #374151; }
  html[data-theme="dark"] .dd-popup-head { border-bottom-color: #1f2937; }
}

/* ===========================================================================
   THE DATE PICKER POPUP BECOMES A BOTTOM SHEET BELOW 760px
   Same conversion as .dd-popup above, applied to the one popup the spec names
   by name and the block above missed. .cal-popup is a 248px anchored panel
   appended to <body> and positioned against a cell rect by positionFloating
   (production-page.js:734). At 390px the cell it anchors to is the full width
   of the card, so the pop either covers the field it belongs to or lands half
   off an edge, and its day buttons are 28px against rule 6's 44px floor.

   Standing rule 8 says the native <input type="date"> is the PRIMARY path on
   touch and both date cells fall back to it only when window.buildCalendarPopup
   is missing, which it never is. Flipping that branch is a change in
   deliverable-dashboard.js and dd-focus-points-card.js, neither of which this
   pass owns, so this converts the popup instead: full width, bottom anchored,
   80vh capped, 44px targets. Rule 7 asks for exactly that conversion for any
   anchored popover, so the two fixes are not alternatives and this one holds
   even after the native branch lands, for the desktop-narrow case.

   top, left and max-height are INLINE styles written by positionFloating, so
   every one of them needs !important to be overridden. Keyed on width rather
   than (hover: none), matching the .dd-popup block: the reason is the stacked
   full width cell, not the pointer.
   =========================================================================== */
@media (max-width: 760px) {
  .cal-popup {
    position: fixed !important;
    top: auto !important;
    left: 0 !important;
    max-height: 80vh !important;
    right: 0;
    bottom: 0;
    width: 100%;
    max-width: 100%;
    display: flex;
    flex-direction: column;
    padding: 0 14px calc(14px + env(safe-area-inset-bottom, 0px));
    border: none;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -12px 40px rgba(15, 23, 42, .28);
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  /* The ddSheet grab pill, so a converted popup reads as the same component as
     every other sheet on the page. Decorative only, exactly as it is on
     .dd-popup: this popup has no explicit close control, it dismisses on an
     outside tap and on a day press, so the pill must not be the only way out
     and it is not presented as one. */
  .cal-popup::before {
    content: '';
    flex: 0 0 auto;
    align-self: center;
    width: 40px;
    height: 4px;
    margin: 10px 0 8px;
    border-radius: 2px;
    background: #d1d5db;
  }

  /* Head pinned, grid owns the scroll. Without min-height: 0 a twelve-month
     year grid refuses to shrink inside the flex column and pushes past the 80vh
     cap, which is the same trap the .dd-popup body carries a note about. */
  .cal-head {
    flex: 0 0 auto;
    margin-bottom: 10px;
  }
  .cal-title { font-size: 15px; }
  .cal-nav {
    width: var(--ddm-tap, 44px);
    height: var(--ddm-tap, 44px);
    font-size: 18px;
  }
  .cal-dow { flex: 0 0 auto; }
  .cal-dow span { font-size: 11px; }
  .cal-grid {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    gap: 4px;
  }
  /* Rule 6. A 28px day in a full width sheet is a mis-tap waiting to happen,
     and picking the wrong date on a content calendar moves a post. */
  .cal-day {
    height: var(--ddm-tap, 44px);
    font-size: 15px;
  }
  .cal-foot {
    flex: 0 0 auto;
    padding-top: 10px;
  }
  .cal-clear {
    min-height: var(--ddm-tap, 44px);
    padding: 0 16px;
  }
}

@media (max-width: 760px) {
  html[data-theme="dark"] .cal-popup {
    box-shadow: 0 -12px 40px rgba(0, 0, 0, .6);
  }
  html[data-theme="dark"] .cal-popup::before { background: #374151; }
}
