/* ===== WEEK PLANNER ===== */

.week-planner-wrap {
  display: flex;
  flex-direction: column;
}

.week-planner-page {
  padding: 24px;
  max-width: 1100px;
  margin: 0 auto;
  width: 100%;
}

/* Mobile scroll: the *scrollable area* itself reaches the true screen edges (no outer padding
   layer narrowing how much of the board a scroll can ever reveal), but the board's own content
   still gets a small resting gutter from those edges — per direct request, a visible inset without
   it "cropping" the scroll. The gutter lives as .week-board's own padding, *inside* the scroll
   container, rather than as surrounding page padding: it shows at both scroll extremes (a small
   gap before Morning at rest, another after Evening once fully scrolled) without ever reducing the
   actual scrollable width, since .week-board-header/.week-day-block's min-width:100% (below)
   already resolves against .week-board's post-padding content box. */
@media (max-width: 768px) {
  .week-planner-page {
    padding-left: 12px;
    padding-right: 12px;
  }
  .week-board {
    margin-left: -12px;
    margin-right: -12px;
    padding-left: 10px;
    padding-right: 10px;
  }
  /* .grid-area's own shared 20px side padding (cards.css, every page in the app) is the other
     layer between .week-board and the true screen edge — same :has() scoping convention
     cards.css/kanban.css/dashboard.css already use for a page-specific grid-area tweak, so this
     doesn't touch any other view. Its overflow-x: hidden stays — .week-board already scrolls
     entirely within its own box regardless, so nothing here needs that safety backstop removed. */
  .grid-area:has(.week-planner-wrap) {
    padding-left: 0;
    padding-right: 0;
  }
}

.wp-page-title {
  font-size: 22px;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 4px;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* Sits inline right after the tagline text (an ordinary inline-block within .wp-page-tagline's own
   <p>, not a flex wrapper) so that paragraph's own text-align:center keeps the tagline+icon
   centered as one unit — moved here from beside the title (an <h1>) above, per direct request
   ("move the info icon so it's on the same line as the tagline"). Reopens the planner setup
   questions (weekPlanner.js's _openOnboardingModal) — no italic/etc. inherited from the tagline,
   since it's an icon, not text. */
.wp-page-info-btn {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  margin-left: 8px;
  padding: 0;
  border: none;
  background: none;
  color: var(--text-secondary, var(--text-primary));
  opacity: 0.7;
  cursor: pointer;
}
.wp-page-info-btn:hover {
  opacity: 1;
  color: var(--primary);
}

.wp-page-tagline {
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 12px;
  text-align: center;
  font-style: italic;
}

/* ── onboarding modal ── */
.wp-onboard-desc {
  font-size: 16px;
  /* Fixed white rather than var(--text-primary), now that the modal's own background is a fixed
     SaveCraft purple (below) regardless of theme — var(--text-primary) would go near-black in
     light mode, unreadable against that purple. */
  color: #fff;
  line-height: 1.35;
  margin-bottom: 14px;
  padding-bottom: 15px;
  text-align: center;
}
/* Reusable "detail/description" container — a lighter panel that sets an explanatory aside apart
   from the rest of a step's own question/fields (first used for step 3's work-block disclaimer,
   originally matching "the background behind the afternoon column text" exactly, then lightened
   further per direct request). Built the same way as that Afternoon-column tint
   (.week-board-header::before) — a translucent white overlay on top of this modal's own
   var(--primary) background — just a stronger opacity, since matching that tint exactly read as
   too subtle once seen as its own standalone container rather than a thin header strip. Holds
   plain `.wp-onboard-desc` text, unchanged — this is a background/shape convention, not a new text
   style. See Popup-rules.md for when to reach for this vs. a plain (uncontained) `.wp-onboard-desc`
   paragraph. */
#wp-onboard-step3 .wp-onboard-detail-box {
  background: rgba(255, 255, 255, 0.25);
  border-radius: 10px;
  padding: 10px 14px;
}
/* Mobile only, per direct request — the popup started scrolling on a real device (the fixed
   height, comfortable on desktop testing, apparently isn't on every real mobile browser/font
   configuration). Reclaims a little vertical room from the tallest part of step 3's content
   rather than growing the popup further. */
@media (max-width: 768px) {
  #wp-onboard-step3 .wp-onboard-detail-box {
    padding: 8px 12px;
  }
  #wp-onboard-step3 .wp-onboard-detail-box .wp-onboard-desc {
    font-size: 14px;
  }
}
/* The shared .wp-onboard-desc rule's own 15px padding-bottom AND 14px margin-bottom (together
   meant to separate one paragraph from whatever follows it outside a container) both stack on top
   of the box's own 10px bottom padding when it's the last thing inside this container — reported
   live as too much space at the bottom (measured: 24px net, not the intended 10px — padding-bottom
   was zeroed in an earlier pass, but margin-bottom was missed, still contributing its own 14px).
   Zeroed only for the last paragraph in the box; an earlier paragraph (the "Work appears in gray."
   lead) doesn't reach this selector and keeps its own spacing as-is. */
#wp-onboard-step3 .wp-onboard-detail-box .wp-onboard-desc:last-child {
  padding-bottom: 0;
  margin-bottom: 0;
}
/* Step 3's "Work appears in gray." lead, split onto its own line above the rest of the
   disclaimer per direct request — same treatment the work-notice popup's own lead line already
   uses (.wp-work-notice-lead). Tightens the shared .wp-onboard-desc's own 14px margin-bottom +
   15px padding-bottom down to a single 8px gap, since the two paragraphs are meant to read as one
   block, not two separately-spaced ones. */
#wp-onboard-step3 .wp-onboard-work-lead {
  font-weight: 700;
  margin-bottom: 5px;
  padding-bottom: 0;
  /* Was margin-top:-5px (a fix from before this text lived inside .wp-onboard-detail-box, meant to
     trim the gap from the days form-group above) — now that a container wraps this text with its
     own top padding, that negative margin pulled the lead up *into* the container's own padding
     instead, breaking the "same padding above the title as below the body text" symmetry the box
     is supposed to have. Left at the default 0 so the container's own 10px top padding (matching
     its 10px bottom) is what actually shows. */
  margin-top: 0;
}
/* Step 1's tagline sits right after the modal header, which carries its own 24px margin-bottom
   (shared .modal-header rule, addEditModal.css) — per direct request this needed to read as 8px
   below the title specifically, so the negative margin here cancels that 24px down to net 8px,
   without touching the header's own margin (shared by steps 2/3, which don't have a tagline). */
#wp-onboard-step1 .wp-onboard-tagline {
  margin-top: -16px;
}

/* The onboarding modal's own question labels (shared .form-group label, addEditModal.css) read
   white, per direct request — sized up a step from the shared 11px, per direct request ("all the
   text... is a little small for reading") — scoped to this modal only, not every .form-group
   label in the app. Sentence case rather than the shared rule's uppercase, per direct request —
   the label text itself is already authored in sentence case (weekPlanner.js), so this only
   needed the transform/letter-spacing (tuned for all-caps) turned off, not any text changes. */
#wp-onboarding-modal-overlay .form-group label {
  color: #fff;
  font-size: 16px;
  text-transform: none;
  letter-spacing: normal;
  /* Centered per direct request ("center the text in the setup modal") — the shared rule's own
     display:flex means text-align has no effect here, justify-content does. */
  justify-content: center;
}
/* Same "a little small for reading" pass — the day-of-week pills (shared with the Edit Activity
   popup's own Days row, scoped here so that one is unaffected) and the 4-box time frame fields. */
#wp-onboarding-modal-overlay .wp-card-modal-day span {
  font-size: 13px;
  /* White-outlined ghost look when not selected — same "outline until selected" treatment as
     Skip — per direct request, replacing an earlier solid-white/purple-text unchecked look (the
     shared rule's own var(--surface)/var(--text-secondary) unchecked look was a dark "menu" box
     against this modal's fixed purple either way). */
  background: transparent;
  border-color: #fff;
  color: #fff;
}
/* Selected state is the inverse — solid white fill, purple text — per direct request, replacing
   an earlier filled-purple/white-text look (which the shared rule's own selected style already
   was, indistinguishable from this modal's own purple background). */
#wp-onboarding-modal-overlay .wp-card-modal-day input:checked + span {
  background: #fff;
  border-color: #fff;
  color: var(--primary);
}
/* 15px, matching step 1's own wake/lunch fields' font-size below — same "same style as the first
   screen" pass. */
#wp-onboarding-modal-overlay .wp-card-modal-time-field,
#wp-onboarding-modal-overlay .wp-card-modal-timeframe-sep {
  font-size: 15px;
}
/* Narrower than the shared 22px (weekPlanner.css's own .wp-card-modal-timeframe rule, still used
   as-is by the Edit Activity popup), per direct request — scoped to this modal only. */
#wp-onboarding-modal-overlay .wp-card-modal-time-field {
  width: 18px;
}
/* Steps 2/3's own 4-box time-frame fields (wp-onboard-item-time / wp-onboard-work-time) get the
   same "remove the dark box" treatment as the plain text/time inputs above — the shared
   .wp-card-modal-timeframe wrapper otherwise fills with var(--surface) too. */
#wp-onboarding-modal-overlay .wp-card-modal-timeframe {
  background: transparent;
  border-color: #fff;
  /* Each number box already centers its own digits (shared .wp-card-modal-time-field rule's own
     text-align:center), but the group of boxes is only as wide as their own fixed 18px-each width
     — as a flex row with no justify-content set, that left the whole "7 : 00 – 8 : 00" cluster
     flush against the wrapper's left edge, with all the spare width sitting empty on the right.
     Centering the row itself is what actually centers it within the full-width field, matching
     step 1's own wake/lunch input where the single value fills (and centers within) the whole box. */
  justify-content: center;
}
#wp-onboarding-modal-overlay .wp-card-modal-timeframe:focus-within {
  border-color: #fff;
}
/* AM/PM for step 1's wake/lunch questions (wp-onboard-time-single) — a plain typed field rather
   than a 2-button toggle, per direct request ("just allow the user to type in the am or pm"),
   pre-filled with the field's own correct default so that value doubles as the example of what to
   type. Same transparent/white-outline look as the hour:minute boxes beside it, sized for 2
   characters and set apart with a small left margin/border so it still reads as its own field. */
/* No border/pill of its own, per direct request ("remove the am and pm buttons") — the outlined-
   box look read as a separate button even though it's always been a plain typed field, never an
   actual button. Plain text now, same as the hour/minute digits beside it (which read as part of
   one field precisely because they don't have their own individual boxes either). */
#wp-onboarding-modal-overlay .wp-onboard-ampm-input {
  width: 30px;
  flex: 0 0 auto;
  margin-left: 4px;
  padding: 0;
  border: none;
  background: transparent;
  color: #fff;
  font-size: 15px;
  font-weight: 400;
  text-align: center;
  text-transform: uppercase;
  outline: none;
}
/* Now a `placeholder` example ("AM"/"PM") rather than a real pre-filled value — same "white not
   gray" pass as every other placeholder-driven field in this popup. */
#wp-onboarding-modal-overlay .wp-onboard-ampm-input::placeholder {
  color: rgba(255, 255, 255, 0.8);
  opacity: 1;
  text-transform: uppercase;
}
/* These boxes show a suggested time via the `placeholder` attribute (_setTimeFramePlaceholders),
   not a real `value` — the `color` above only affects typed-in text, so the placeholder itself
   still rendered in the browser's own default gray. Whitened per direct request ("the text inside
   the fields on the second and third screens white not gray"). */
#wp-onboarding-modal-overlay .wp-card-modal-timeframe input.wp-card-modal-time-field {
  color: #fff;
}
#wp-onboarding-modal-overlay .wp-card-modal-timeframe input.wp-card-modal-time-field::placeholder {
  color: rgba(255, 255, 255, 0.8);
  opacity: 1;
}
#wp-onboarding-modal-overlay .wp-card-modal-timeframe-sep {
  color: #fff;
  opacity: 0.8;
}
/* Step 1's wake/lunch questions no longer use a native input[type="time"] (see
   _singleTimeFieldsValue in weekPlanner.js) — this now only styles step 2's item-name field. */
#wp-onboarding-modal-overlay input[type="text"] {
  font-size: 15px;
  /* The shared .form-group input rule (addEditModal.css) fills these with var(--surface) — a dark
     box in dark mode, reading like a separate menu/dropdown surface sitting on top of this modal's
     own fixed purple. Removed per direct request ("remove the menu background from this popup") so
     the fields blend into the purple instead, with a white outline in its place (matching the
     Skip/Save buttons' own white-on-purple treatment) and white text so it still reads against the
     purple regardless of the page's own light/dark theme. */
  background: transparent;
  border-color: #fff;
  color: #fff;
  /* Standing rule for this popup — every field's own text/placeholder is centered, matching the
     time fields beside it (this one was left at the browser's default left-align until now). */
  text-align: center;
}
#wp-onboarding-modal-overlay input[type="text"]:focus {
  border-color: #fff;
}
/* Shows a real placeholder ("e.g. Stretch") — same "white not gray" pass as the time-frame boxes
   above. */
#wp-onboarding-modal-overlay input[type="text"]::placeholder {
  color: rgba(255, 255, 255, 0.8);
  opacity: 1;
}
/* Desktop only, per direct request — every field in this modal (the wake/lunch, item-name, and
   4-box time-frame fields) is otherwise full-width, which reads as oversized with a lot of empty
   space once its own content is this short. Narrowed and re-centered rather than touching mobile,
   where the fields already need all the width they can get. Targets #wp-onboard-item-text
   specifically rather than the generic input[type="text"] selector — the wake/lunch AM/PM field
   is also a type="text" input, and a blanket selector stretched it to fill the row instead of
   staying at its own fixed 32px (its own rule lost that fight on specificity). */
@media (min-width: 481px) {
  #wp-onboard-item-text,
  #wp-onboarding-modal-overlay .wp-card-modal-timeframe {
    width: calc(100% - 40px);
    margin-left: auto;
    margin-right: auto;
  }
  /* <input> is inline-block by default — auto margins don't center an inline-block box the way
     they do a block one, so #wp-onboard-item-text's own margin:auto above silently did nothing
     (reported live: visibly off-center against the timeframe field below it, a <div> and
     therefore already block by default). */
  #wp-onboard-item-text {
    display: block;
  }
}

/* Pins each step's own Skip/Save (Skip/Add, Skip/Finish) row flush to the bottom of the modal box,
   per direct request. .modal sizes to its content by default (no fixed height), so a min-height —
   sized to comfortably fit the tallest step (step 3's time frame + 7 day checkboxes) — gives every
   step's own box the same stable height instead of growing/shrinking as the wizard advances; each
   step wrapper is then a flex column itself (a plain block div gives margin-top:auto on its own
   .modal-actions child nothing to push against) so that child sinks to fill whatever space the
   shared min-height leaves on a shorter step. */
/* The browser's own default caret color is a blue system tint that's invisible against this
   modal's fixed purple background on mobile (reported live) — set explicitly on every input type
   in the modal, not just the text ones, since the 4-box time-frame's number inputs need it too. */
#wp-onboarding-modal-overlay input {
  caret-color: #000;
}
#wp-onboarding-modal-overlay .modal {
  /* A firm height, not min-height — min-height was re-tuned twice already (400px, then 428px) as
     step 3 kept growing its own content (the AM/PM fields, the detail-box container, ...) past
     whatever the floor happened to be at the time, each time visibly reintroducing "the popup's
     height changes as you navigate" after it had already been reported fixed once. A generous
     fixed height that comfortably clears every step's current content (step 3's own natural height
     measures ~429px; this leaves real headroom above that, not just a few px) makes the box's
     height a hard invariant instead of something that has to be perfectly re-measured after every
     future content tweak — a future step can still grow noticeably taller without silently
     breaking this again. `height` (not min-height) still respects the shared .modal's own smaller
     max-height (85vh/85dvh) on a genuinely short mobile viewport — max-height always wins over a
     conflicting height per the CSS spec, so this doesn't reintroduce a mobile overflow risk. */
  height: 445px;
  /* Reported live: even with each step's own fields then centered, the shared .modal's own 28px
     bottom padding (addEditModal.css) still left a visibly large gap below the Skip/Save row
     itself, distinct from the space around the fields — tightened to 14px, just for this modal.
     Now that .modal-body is top-aligned instead (see below) and Skip/Save sit right at the bottom
     of a fixed-height box, 14px read as too tight against the edge — bumped back up per direct
     request. box-sizing:border-box (base.css) means this comes out of the same min-height rather
     than growing the modal, per direct request not to make the popup taller. */
  padding-bottom: 24px;
  /* SaveCraft purple background, per direct request — same var(--primary) the app's own purple
     accents/buttons already use, fixed regardless of theme (unlike the shared .modal's own
     var(--modal-bg), which flips dark/light). */
  background: var(--primary);
}
/* Mobile only, per direct request — 10px more breathing room below the button row than desktop
   gets. Both height and padding-bottom go up by the same 10px, so that extra space comes in as
   pure added padding rather than eating into the existing content area (box-sizing:border-box
   would otherwise just shrink the content box by whatever padding-bottom alone increased). */
@media (max-width: 768px) {
  #wp-onboarding-modal-overlay .modal {
    height: 455px;
    padding-bottom: 34px;
  }
}
/* Back arrow, top-left corner of the popup — per direct request, steps the wizard back one step
   instead of closing it. Hidden on step 1 (nowhere to go back to), toggled by showStep in
   _ensureOnboardingModal. Positioned against .modal itself (already position:relative) rather
   than .modal-header, so it sits at the corner of the whole popup regardless of the header's own
   padding. */
#wp-onboarding-modal-overlay .wp-onboard-back-btn {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 1;
  padding: 4px;
  background: none;
  border: none;
  color: #fff;
  cursor: pointer;
  display: flex;
}
/* "Setup Planner" inherits var(--text-primary) from body otherwise (no .modal-header h2 rule of
   its own) — would go near-black in light mode against the modal's fixed purple background. The
   header banner behind it (white, then dark) has been removed per direct request, so the title
   now just sits directly on that purple like the rest of the modal. */
#wp-onboarding-modal-overlay .modal-header h2 {
  color: #fff;
}
/* Save/Add/Finish (.btn-primary, shared with every other modal in the app) is background:
   var(--primary); color: white by default — identical to the modal's own new background, so the
   button would be invisible but for its text. Inverted here to a white pill with purple text
   instead, mirroring the same "white pill on purple" treatment the Edit Activity modal's own
   header Save button already uses (.purple-header-save-btn) — hover swaps it back to purple with a
   white border so it stays visible against the same purple modal underneath it. */
#wp-onboarding-modal-overlay .modal-actions .btn-primary {
  background: #fff;
  color: var(--primary);
  border: 2px solid transparent;
}
#wp-onboarding-modal-overlay .modal-actions .btn-primary:hover {
  /* Plain transparent outline, not var(--primary-hover) — that token resolves to a different
     purple shade than the modal's own var(--primary) background, reported live as a visibly
     mismatched second purple flashing in on hover. */
  background: transparent;
  color: #fff;
  border-color: #fff;
}
/* Skip (.btn-cancel, shared with every other modal in the app) is normally a var(--surface)-
   filled box with a var(--border) outline — reads fine as a neutral button, but per direct request
   this modal's Skip is instead a plain white outline with white text against the purple background
   (a ghost button), filling solid white with purple text on hover — same size/border-width as the
   Save pill beside it (2px) so the two stay visually matched. */
#wp-onboarding-modal-overlay .modal-actions .btn-cancel {
  background: transparent;
  border: 2px solid #fff;
  color: #fff;
}
#wp-onboarding-modal-overlay .modal-actions .btn-cancel:hover {
  background: #fff;
  color: var(--primary);
}
#wp-onboarding-modal-overlay #wp-onboard-step1,
#wp-onboarding-modal-overlay #wp-onboard-step2,
#wp-onboarding-modal-overlay #wp-onboard-step3,
#wp-onboarding-modal-overlay #wp-onboard-step4 {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
/* The shared modal height (above) is sized for step 3's own content, the tallest of the three —
   its natural height comes to 414px, barely under the 420px total, so the height itself isn't
   oversized. Step 1/2 just have much less content, and previously it all stacked at the very top
   with Skip/Save pinned to the bottom (margin-top:auto below), dumping every bit of the leftover
   space into one gap right above the buttons — reported live as looking unbalanced, distinct from
   wanting the steps to actually vary in height (they still share the one fixed total above).
   Centering each step's own fields vertically within its available space instead spreads any
   leftover room evenly above and below them — for step 3, there's barely any to redistribute, so
   this is a no-op there. */
#wp-onboarding-modal-overlay .modal-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  /* Centers each step's own fields vertically between the header and Skip/Save, per direct
     request ("on all the screens vertically center the content between the title and the
     buttons") — briefly top-aligned instead (see git history), reverted back to centered. */
  justify-content: center;
  min-height: 0;
}
#wp-onboarding-modal-overlay .modal-actions {
  /* A fixed minimum instead of margin-top:auto, per direct request ("the negative space above the
     buttons doesn't have to be the same on each state but the buttons should always have a
     standard minimum padding around them") — auto lets modal-body's own centering claim ALL the
     leftover space right up to the buttons, which shrinks to near-zero on a content-heavy step
     (step 4). A fixed 24px (matching the modal's own bottom padding, above) guarantees that floor
     on every step regardless of how much content precedes it; any extra room still varies step to
     step via modal-body's own centering above this fixed gap. */
  margin-top: 24px;
  /* Centered rather than the shared rule's right-aligned flex-end, per direct request. */
  justify-content: center;
}
/* Step 4's small static mockup of a real activity card (view mode), per direct request — modeled
   on the real popup's own .purple-header-bar/.purple-header-save-btn/.wp-card-modal-link-btn, but
   as its own classes at a smaller scale since it's never a real interactive card. Header inverted
   to white-on-purple (rather than the real card's own purple-on-neutral) so it actually stands out
   against this modal's own solid-purple background, matching every other white-against-purple
   element already in this modal; the body keeps the real card's own dark surface color so the
   "+ Content Options" line still reads in its real color (var(--primary) on dark). */
#wp-onboarding-modal-overlay .wp-onboard-card-preview {
  width: 100%;
  max-width: 260px;
  margin: 0 auto;
  border-radius: 10px;
  overflow: hidden;
  border: 1.5px solid #fff;
}
#wp-onboarding-modal-overlay .wp-onboard-card-preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
  background: #fff;
  color: var(--primary);
  font-size: 12px;
  font-weight: 700;
}
#wp-onboarding-modal-overlay .wp-onboard-card-preview-edit {
  flex-shrink: 0;
  background: var(--primary);
  color: #fff;
  border-radius: 20px;
  padding: 2px 10px;
  font-size: 10px;
  font-weight: 700;
}
#wp-onboarding-modal-overlay .wp-onboard-card-preview-body {
  background: #25262B;
  padding: 16px 12px;
  text-align: center;
}
#wp-onboarding-modal-overlay .wp-onboard-card-preview-title {
  color: #fff;
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 12px;
}
#wp-onboarding-modal-overlay .wp-onboard-card-preview-options {
  display: inline-block;
  padding: 6px 14px;
  border: 1.5px dashed rgba(255, 255, 255, 0.4);
  border-radius: 8px;
  color: var(--primary);
  font-size: 11px;
  font-weight: 600;
}
#wp-onboarding-modal-overlay .wp-onboard-card-preview-caption {
  margin: 10px 0 0;
  color: #fff;
  font-size: 13px;
  text-align: center;
  opacity: 0.85;
}
/* Skip and Save/Add/Finish otherwise size to their own text ("Skip" vs "Finish" etc.), reading as
   mismatched at a glance — per direct request, both buttons in the row get the same fixed width. */
#wp-onboarding-modal-overlay .modal-actions button {
  width: 120px;
  /* Bolder and a step up from the shared 14px, per direct request — .btn-cancel has no
     font-weight of its own (default 400) and .btn-primary's own 500 both read as too light/small
     against this popup's bigger 16px labels/fields. */
  font-size: 15px;
  font-weight: 700;
}

/* "Work" name heads-up (weekPlanner.js's _ensureWorkNoticeModal) — the reference implementation
   of the app-wide "About notice style" (single-button acknowledgment). Its actual CSS
   (.about-notice-*) now lives in misc.css, generic and un-scoped, so the next "About X" one-time
   explainer notice can reuse it directly instead of copying this block under a new name. */

/* ── the week itself: 7 stacked day blocks, per the screenshot's row-per-day layout ── */
.week-board {
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* Horizontal scroll on narrow/mobile widths instead of squeezing the 3 sections unreadably
     thin, per direct request — same overflow-x:auto + a per-column min-width pattern
     kanban.css's own .kanban-board/.kanban-column already use, just for a column-stacked board
     of day-rows instead of one row of Kanban columns. The header row and every day row share the
     same min-width per column (below), so they all overflow/scroll in lockstep. */
  overflow-x: auto;
}

/* One shared column header above the whole week (Morning/Afternoon/Evening) instead of repeating
   it per day block. Same 14px horizontal padding as .week-day-block below, so its 3 columns line
   up with every day row's cells — gap:0 to match, per direct request ("the bar is wider than the
   week content sections"): this used to be gap:14px, a stale mismatch against .week-day-cells'
   own gap:0 below (needed there for .week-day-middle-tint's positioning math) that left the header
   consistently ~28px wider than every day row regardless of content. */
.week-board-header {
  display: flex;
  gap: 0;
  padding: 10px 14px;
  background: var(--primary);
  border-radius: 10px;
  /* Opts out of .week-board's default column-flex stretch, which would otherwise cap this at the
     visible viewport width and clip the overflow .week-board's own overflow-x:auto is meant to
     scroll instead — min-width keeps it full-width on a normal (non-scrolling) desktop screen. */
  align-self: flex-start;
  min-width: 100%;
  /* Anchors the Afternoon tint below (position:absolute) and contains its negative z-index, same
     pairing .week-day-block/.week-day-middle-tint already use. */
  position: relative;
  isolation: isolate;
}

.week-board-header-col {
  flex: 1 1 0;
  min-width: 170px; /* matches .week-cell's own min-width below, so the header never scrolls out
                        of alignment with the day rows underneath it */
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
  text-align: center;
}
/* Afternoon (always the middle of the 3 — SECTIONS in weekPlanner.js is fixed Morning/Afternoon/
   Evening) gets a lighter tone than Morning/Evening's plain --primary, per direct request —
   mirrors .week-day-middle-tint's own "Afternoon reads lighter" treatment below the header,
   including its technique: a dedicated absolutely-positioned layer spanning the bar's full
   top:0/bottom:0, not a background on .week-board-header-col itself. A background on that flex
   item only fills its own content box, inset from the bar's true top/bottom edges by
   .week-board-header's own 10px vertical padding — reported live, screenshot showed the tint
   floating short of both edges instead of touching them. Horizontal position/width mirror
   .week-day-middle-tint's own math exactly (same 14px horizontal padding, same gap:0, same 3 equal
   columns) so both tints line up vertically with each other. A translucent white overlay (same
   technique .week-card--work uses to lighten a card over its own var(--surface)) rather than
   --hover-bg directly, since that token is tuned to sit on this app's neutral surface/bg colors,
   not to read well layered on --primary's purple. */
.week-board-header::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(14px + (100% - 28px) / 3);
  width: calc((100% - 28px) / 3);
  background: rgba(255, 255, 255, 0.15);
  z-index: -1;
}

.week-day-block {
  position: relative; /* positions .week-day-middle-tint below */
  isolation: isolate; /* contains that tint's negative z-index to this block, so it can't paint
                          behind unrelated content further up the page */
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  /* Same reasoning as .week-board-header's own align-self/min-width above — without this, the
     column-flex stretch from .week-board caps every day block at the viewport width, clipping
     its 3 sections instead of letting the board scroll to reveal them. */
  align-self: flex-start;
  min-width: 100%;
}

/* Afternoon's light-gray tint, as a dedicated absolutely-positioned layer spanning the block's
   full height (top:0/bottom:0 of .week-day-block itself) instead of a background on .week-cell —
   a per-cell background can only bleed as far as that cell's own box, which sits below the day
   label (.week-day-label) and can't reach past it to the block's true top edge; this layer is
   independent of the label's height entirely. Horizontal position/width mirror .week-cell's own
   math (day-block's 14px padding each side, the middle third of what's left, no gap between the 3
   cells) so it lines up with the actual middle column beneath it. --hover-bg reads as a light gray
   in both themes (unlike --bg, which is darker than --surface in dark mode) — safe to use here
   since the drag-over highlight below now matches kanban.css's own .kanban-column--over instead of
   reusing this same token. */
.week-day-middle-tint {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(14px + (100% - 28px) / 3);
  width: calc((100% - 28px) / 3);
  background: var(--hover-bg);
  z-index: -1;
}

.week-day-label {
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 10px;
}

.week-day-cells {
  display: flex;
  /* No gap — the 3 columns need to read as flush table columns, matching .week-day-middle-tint's
     own no-gap math above. */
  gap: 0;
  align-items: flex-start; /* sections are variable-height on desktop — Morning might have 3 cards,
    Afternoon 1 (mobile overrides each .week-cell to a shared fixed height instead — see there) */
}

.week-cell {
  flex: 1 1 0;
  /* A real floor (not 0), per direct request — on mobile this makes the 3 sections refuse to
     squeeze past readable card width; .week-board's own overflow-x:auto (above) turns that into
     a horizontal scroll instead, same as kanban.css's .kanban-column min-width does for the
     Kanban board. */
  min-width: 170px;
  display: flex;
  flex-direction: column;
  padding: 6px 10px;
  transition: background-color 0.15s;
}
.week-cell--over {
  background: var(--primary-bg);
  outline: 2px dashed var(--primary);
  outline-offset: -2px;
}

.week-cell-cards {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 8px; /* keeps an empty cell a real drop target, not a zero-height sliver */
  /* One more link in the same min-width:auto chain .week-card fixes below — this flex item
     (a column flex child of .week-cell) still defaulted to auto, which computes an automatic
     minimum from its own content's intrinsic size regardless of any width/min-width already set
     further down the tree. Verified live: with .week-card's own min-width:0/width:100% alone, a
     long unbroken word still inflated THIS container (and with it .week-cell/.week-day-block)
     well past where the text itself visibly truncated inside .wp-card-text. */
  min-width: 0;
}

/* On mobile, width should be identical for every day (a fixed column, not content-driven — see
   flex/width below), but per direct request height should NOT be forced identical across days:
   one day's Evening still lines up with that SAME day's own Morning/Afternoon (the natural
   tallest-of-the-3 flex behavior above already does that, sharing .week-day-block's one
   background/border), but a day with more cards is free to grow taller than a quieter day right
   below it — min-height only, not height, so nothing here caps or forces growth. The floor keeps
   an empty day comfortably tappable ("+Add" etc.) without needing any content in it yet. */
@media (max-width: 768px) {
  .week-cell {
    min-height: 260px;
    /* Reported live: a long unbroken word/link in one card still inflated every column together,
       header included, despite the truncation above visibly working on the text itself. Root
       cause: white-space: nowrap makes that text's own intrinsic (max-content) width the full
       unwrapped string — overflow: hidden only clips *rendering* once a size is assigned, it never
       shrinks what an ancestor's auto-sizing pass considers this content to "want". With .week-cell
       still flex: 1 1 0 (grow-enabled, no fixed basis), that inflated want gets redistributed
       equally across all 3 columns during that sizing pass. A hard fixed width sidesteps the whole
       calculation, independent of the min-height above — a cell just grows taller for its own
       content instead of ever asking to be wider. */
    flex: 0 0 170px;
    width: 170px;
  }
}

.week-cell-add-btn {
  align-self: flex-start;
  margin-top: 6px;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 12px;
  cursor: pointer;
  padding: 2px 4px;
}
.week-cell-add-btn:hover {
  color: var(--primary);
}

/* ── one activity card — layered on .kcard (shared box/border/drag styling), overriding its
   fixed 100px library-card height down to something compact ── */
.week-card {
  height: auto;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  cursor: pointer; /* the whole card opens the edit popup on click (weekPlanner.js) */
  /* A flex item (.week-cell-cards is display:flex; flex-direction:column) defaults to
     min-width: auto, not 0 — same fix as .modal-body/.detail-tracklist-item elsewhere in this
     app. Without it, a long unbroken activity name (or link pasted into Notes) can refuse to
     shrink below its own content width despite .wp-card-text's truncation, forcing this one card
     — and with it .week-cell-cards, .week-cell, and the whole .week-day-block row — wider than
     every other card/section. Reported live: cards different sizes from each other, sections
     growing with content, and the shared Morning/Afternoon/Evening header ending up narrower than
     a section that had inflated this way. */
  min-width: 0;
  width: 100%;
}
/* Colored left accent stripe for a non-weekly card, per direct request — amber/violet rather than
   --primary's purple, since that color already means "active/selected" elsewhere in this app. A
   plain weekly card gets no override here, so it looks exactly as it always has. */
.week-card--biweekly {
  border-left: 3px solid #F59E0B;
}
.week-card--monthly {
  border-left: 3px solid #A855F7;
}
/* A lighter-gray background for a work-block card (isWorkBlock, weekPlanner.js), per direct
   request — a translucent white overlay rather than a hardcoded hex, so it reads as "lighter than
   this card would otherwise be" against .kcard's own var(--surface) background in both themes,
   rather than only being tuned for the dark theme every screenshot this session has been in. */
.week-card--work {
  background: rgba(255, 255, 255, 0.06);
}

.wp-card-fields {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
}
/* Time stacks above the activity name on mobile, per direct request, instead of sitting side by
   side — the narrower per-column width there (.week-cell's own 170px min-width) leaves less room
   for both on one line. Desktop keeps the row layout above. */
@media (max-width: 768px) {
  .wp-card-fields {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }
  /* align-items: flex-start above (needed for left-aligning the short time line over the longer
     name) has a side effect on a *column* flex container: without an explicit stretch, a child
     sizes to its own intrinsic content width instead of the row's — so .wp-card-text's existing
     white-space:nowrap/overflow:hidden/text-overflow:ellipsis never actually triggers, since its
     box just grows to fit the whole name instead of being constrained. Reported live: a long name
     ("Lindy Bomb Squad") ran out past the card's own edge, under the icon, with no ellipsis at all.
     align-self: stretch restores a real width to shrink against, without touching .wp-card-time
     (still sizes to its own short "8:00-9:00" content, which is what flex-start was for). */
  .wp-card-text {
    align-self: stretch;
  }
}
.wp-card-time {
  flex: 0 0 auto;
  min-width: 44px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
  border-radius: 3px;
  padding: 1px 2px;
}
.wp-card-text {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--text-primary);
  border-radius: 3px;
  padding: 1px 2px;
  /* Truncate instead of wrapping — without this, the recurrence badge below (flex-shrink: 0,
     sharing this same row) can squeeze this span down to almost nothing, wrapping the activity
     name one character per line. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Shown in place of a blank time/text field — the card itself is no longer editable inline (see
   .week-card's cursor:pointer below and _openCardModal in weekPlanner.js), so there's no live
   contenteditable state to style here anymore, just this static placeholder text. */
.wp-card-field-empty {
  color: var(--text-muted);
}

/* Recurrence badge — same small-pill visual language as cards.css's .card-badge (uppercase,
   rounded, small), not reused directly since that class carries category-color hooks that don't
   apply here. Colors match .week-card--biweekly/--monthly's own accent stripe. */
.wp-card-recurrence-badge {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 12px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: #fff;
  white-space: nowrap;
}
.wp-card-recurrence-badge--biweekly {
  background: #F59E0B;
}
.wp-card-recurrence-badge--monthly {
  background: #A855F7;
}

/* Brief inline rejection notice when a time (typed or dropped) would overflow its section's
   designated hours — same red as showSyncErrorBanner's own error convention (main.js), just small
   and local instead of a full-width page banner, since this is self-explanatory and tied to one
   specific field or cell. */
.wp-time-fit-error {
  font-size: 11px;
  color: #fff;
  background: #B91C1C;
  padding: 3px 8px;
  border-radius: 4px;
  margin-top: 4px;
  display: inline-block;
}

/* Small gradient letter tile — "for now" placeholder per direct request, same
   .kcard-thumb--placeholder mechanics Kanban cards already use for a missing image, just one of a
   handful of fixed gradients (weekPlanner.js's CARD_COLORS, chosen through the Edit Activity
   popup's own Icon color swatches) instead of Kanban's per-category palette, since a Week Planner
   card has no category to vary by. Purple is the default/original look, kept byte-for-byte the
   same as before this was pickable. */
.wp-card-thumb {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  font-size: 14px;
  flex-shrink: 0;
}
.wp-card-thumb--purple { background: linear-gradient(135deg, #5B5BEF 0%, #8B85F5 100%); }
.wp-card-thumb--blue   { background: linear-gradient(135deg, #3B82F6 0%, #93C5FD 100%); }
.wp-card-thumb--pink   { background: linear-gradient(135deg, #EC4899 0%, #F9A8D4 100%); }
.wp-card-thumb--yellow { background: linear-gradient(135deg, #EAB308 0%, #FDE047 100%); }
.wp-card-thumb--red    { background: linear-gradient(135deg, #EF4444 0%, #FCA5A5 100%); }
.wp-card-thumb--green  { background: linear-gradient(135deg, #10B981 0%, #6EE7B7 100%); }
.wp-card-thumb--orange { background: linear-gradient(135deg, #F97316 0%, #FDBA74 100%); }
.wp-card-thumb--gray   { background: linear-gradient(135deg, #6B7280 0%, #9CA3AF 100%); }

/* A linked save's thumbnail (real image, or the same letter-tile fallback) gets a 2px outline in
   the activity's own icon color, per direct request — --swatch is set inline per-card (same
   technique .wp-card-modal-color-opt below already uses), so the 7-color map isn't duplicated
   into CSS a second time. .kcard-thumb (kanban.css) supplies object-fit/display for the <img>
   case; .wp-card-thumb here still wins the width/height/border-radius tie (loads after kanban.css). */
.wp-card-thumb--linked {
  border: 2px solid var(--swatch);
}

/* Positioning context for the "+N" badge (more than one save linked, weekPlanner.js's
   _buildCardHtml) — only wraps the thumbnail when at least one save is linked, so a plain
   unlinked card's layout is completely unaffected. */
.wp-card-thumb-wrap {
  position: relative;
  flex-shrink: 0;
}
.wp-card-thumb-count {
  position: absolute;
  bottom: -4px;
  right: -4px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 8px;
  background: var(--primary);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--surface);
}

/* The swatch picker itself, in the Edit Activity popup — a row of small solid-color circles (the
   thumbnail's own gradient is reserved for the actual card; a flat swatch reads more clearly as
   "pick one of these" at this size). The active one gets a ring so it's still identifiable once
   its own border blends into a same-hue swatch. */
.wp-card-modal-color {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.wp-card-modal-color-opt {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid transparent;
  background: var(--swatch);
  cursor: pointer;
  padding: 0;
}
.wp-card-modal-color-opt.active {
  border-color: var(--text-primary);
  box-shadow: 0 0 0 2px var(--surface);
}

/* Sits one below the shared .modal-overlay z-index (addEditModal.css, 550) — per direct request,
   tapping a linked item's icon opens a real save's own modal (detailModal.js's openDetailModal)
   ON TOP of this one, which must stay open underneath rather than closing. Every other app modal
   already shares that same base z-index (a DOM-order tie would otherwise make whichever modal
   happens to exist first in the DOM win, which isn't reliable), so lowering just this one overlay
   guarantees anything opened from inside it always stacks above, regardless of DOM order — and
   each overlay's own independent backdrop-click-to-close (this file's own listener below,
   main.js's for the detail modal) means tapping away closes only the topmost one, leaving this
   modal open until a second tap-away with nothing left on top of it. */
#wp-card-modal-overlay {
  z-index: 549;
}

/* ── activity edit popup — visually modeled on the app's own Edit Item popup
   (addEditModal.css's .modal--edit-item: same 374px/34px-padding size and purple
   header-bar-with-white-Save-pill look). This is the reference implementation of the app-wide
   "Purple-header style" (a purple header bar + white pill action button on an otherwise neutral/
   theme-adaptive modal, for a single-record view/edit popup) — .purple-header-bar/
   .purple-header-save-btn below are genuinely reusable, not this popup's own private classes, so
   the next Purple-header-style popup should reuse them directly rather than re-deriving this
   block under a new name. Kept as its own generic classes rather than sharing
   .modal--edit-item directly, since that one's deeply wired to the unrelated library-item
   wizard. ── */
.wp-card-modal {
  width: 374px;
  padding: 34px;
}
.purple-header-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: -34px -34px 24px;
  background: var(--primary);
  /* Square bottom corners, rounded top only, per direct request — matches .modal's own 16px top
     radius so the bar's top edge still flows into the modal's own rounded corner. */
  border-radius: 16px 16px 0 0;
  padding: 12px 20px;
}
.purple-header-bar h2 {
  color: #fff;
  font-size: 15px;
  margin: 0;
}
.purple-header-save-btn {
  flex-shrink: 0;
  background: #fff;
  color: var(--primary);
  border: 2px solid transparent;
  border-radius: 20px;
  padding: 5px 16px;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.purple-header-save-btn:hover {
  background: var(--primary-hover, var(--primary));
  color: #fff;
  border-color: #fff;
}

.wp-card-modal .form-group input[type="text"] {
  width: 100%;
}

/* Time frame is 4 separate hour/minute boxes (weekPlanner.js's _timeFrameFieldsValue etc.) inside
   one bordered wrapper styled like the app's other .form-group inputs, so it still reads as a
   single field — the boxes themselves carry no border/background of their own. */
.wp-card-modal-timeframe {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  transition: border-color 0.15s;
}
.wp-card-modal-timeframe:focus-within {
  border-color: var(--primary);
}
/* ".wp-card-modal-timeframe input" (not just ".wp-card-modal-time-field") to out-specificity
   addEditModal.css's generic ".form-group input" rule (same 0-1-1 weight, and it's a shared file
   this one can't rely on loading after) — otherwise that rule's own width:100%/padding wins and
   each box balloons to fill the whole wrapper. */
.wp-card-modal-timeframe input.wp-card-modal-time-field {
  width: 22px;
  flex: 0 0 auto;
  border: none;
  padding: 0;
  background: transparent;
  color: var(--text-primary);
  font-size: 14px;
  text-align: center;
  outline: none;
  /* Hides the native up/down spinner (Firefox) — Chrome/Safari's own spinner is hidden by the
     ::-webkit- rule just below. */
  -moz-appearance: textfield;
}
.wp-card-modal-timeframe input.wp-card-modal-time-field::-webkit-outer-spin-button,
.wp-card-modal-timeframe input.wp-card-modal-time-field::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.wp-card-modal-timeframe-sep {
  color: var(--text-secondary, var(--text-primary));
  opacity: 0.6;
  user-select: none;
}
.wp-card-modal-timeframe-dash {
  margin: 0 2px;
}

/* Time needs a fresh value after switching to a different section than the one this activity
   opened with (weekPlanner.js's section-button handler clears the field and adds this) — red
   outline until the user gives it a new time (or switches back, which restores the original and
   removes this). Applied to the whole .wp-card-modal-timeframe wrapper, not the individual boxes,
   so all 4 outline together as one field. */
.wp-card-modal-time-error {
  border-color: #e05252 !important;
  outline: none;
}
/* Onboarding modal's own "you tried to Save/Add/Next with missing content" flash, per direct
   request — same red as .wp-card-modal-time-error above, applied to whichever field(s) are
   missing plus the button itself, and auto-removed ~1s later (weekPlanner.js's own setTimeout,
   not a CSS transition/animation) rather than staying red until the user fixes it. `outline`
   (not `border-color`) for the days row specifically, since .wp-card-modal-days has no border of
   its own to recolor and outline doesn't affect its flex layout. */
#wp-onboarding-modal-overlay .wp-onboard-field-error {
  border-color: #e05252 !important;
}
#wp-onboarding-modal-overlay .wp-card-modal-days.wp-onboard-field-error {
  outline: 2px solid #e05252;
  outline-offset: 4px;
  border-radius: 8px;
}

.wp-card-modal-days {
  display: flex;
  /* No wrap — all 7 fit on one row (see .wp-card-modal-day span's sizing below), per direct
     request; Sunday was previously dropping to its own row underneath. */
  gap: 4px;
}
.wp-card-modal-day {
  position: relative;
  display: inline-flex;
  flex: 1;
  min-width: 0;
  cursor: pointer;
}
.wp-card-modal-day input {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
}
.wp-card-modal-day span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-width: 0;
  height: 32px;
  padding: 0 2px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 11px;
  font-weight: 600;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.wp-card-modal-day input:checked + span {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

.wp-card-modal-section,
.wp-card-modal-recurrence {
  display: flex;
  gap: 6px;
}
.wp-card-modal-section-opt,
.wp-card-modal-recurrence-opt {
  flex: 1;
  padding: 7px 0;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.wp-card-modal-section-opt.active,
.wp-card-modal-recurrence-opt.active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

/* Which week(s) of the month — only shown under Repeats for Biweekly/Monthly (weekPlanner.js).
   Smaller than the Repeats/Section buttons above it (a secondary, narrower-scope choice), same
   active-state color. */
.wp-card-modal-weeks {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}
.wp-card-modal-week-opt {
  flex: 1;
  padding: 5px 0;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}
.wp-card-modal-week-opt.active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

/* View mode — the read-only summary + linked-save control shown by default for an existing card
   (weekPlanner.js's _setCardModalMode/_openCardModal); .wp-card-modal-edit (the original form) is
   its sibling, the two toggled by display:none/'' rather than two separate modals. */
/* The activity's name now lives in the modal's own header title instead (weekPlanner.js's
   _setCardModalMode reads this element's own text to set it) — kept in the DOM as that source but
   hidden here rather than shown a second time right below it. */
/* Swapped with the time|day line, per direct request — the activity name now lives in the body
   (styled the way the time|day line used to be), and the time|day line moved into the header
   title instead (weekPlanner.js's _setCardModalMode now reads #wp-card-modal-view-time for it,
   hidden here rather than shown a second time right below it). */
.wp-card-modal-view-text {
  text-align: center;
  font-size: 19px;
  font-weight: 700;
  /* --text-primary rather than a literal white, per direct request ("white") — this app supports
     a light theme too (base.css), where --text-primary is near-black; using the token instead of
     a hardcoded #fff keeps this readable there while still reading as white in dark mode, which
     every screenshot this session has actually been in. */
  color: var(--text-primary);
  /* This is an <h3> (unlike .wp-card-modal-view-time, a plain <div>) — resets its own UA-default
     top margin too, not just bottom, now that it's actually shown. */
  margin: 0 0 4px;
}
/* The Notes field's own read-only line, directly under the activity title — per direct request.
   Empty (no note saved) collapses to nothing rather than leaving a gap. */
.wp-card-modal-view-notes {
  text-align: center;
  font-size: 14px;
  color: var(--text-secondary);
  margin-bottom: 4px;
  word-break: break-word;
}
.wp-card-modal-view-notes:empty {
  display: none;
}
.wp-card-modal-view-notes a {
  color: var(--primary);
}
.wp-card-modal-view-time {
  display: none;
}
.wp-card-modal-view-recurrence:not(:empty) {
  margin-top: 8px;
}
.wp-card-modal-view-save {
  margin-top: 20px;
}
.wp-card-modal-link-btn {
  width: 100%;
  padding: 9px 0;
  border-radius: 8px;
  border: 1.5px dashed var(--border);
  background: none;
  color: var(--primary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
/* Shown instead of the button once MAX_SAVED_ITEMS is reached (weekPlanner.js's
   _renderLinkedSaveRow), so the picker never opens onto an already-full list. */
.wp-card-modal-link-limit {
  text-align: center;
  padding: 9px 0;
  font-size: 12px;
  color: var(--text-secondary, var(--text-primary));
  opacity: 0.6;
}
/* A linked item block sitting above the button/limit line needs its own separation, same as the
   divider between multiple linked items above. */
.wp-card-modal-linked-item + .wp-card-modal-link-btn,
.wp-card-modal-linked-item + .wp-card-modal-link-limit {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
/* Each linked item is its own block (thumbnail/title/unlink row + its own note) — up to
   MAX_SAVED_ITEMS of these stack with a divider between them, per direct request ("up to 10
   items"). */
.wp-card-modal-linked-item + .wp-card-modal-linked-item {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.wp-card-modal-linked-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* Wraps the thumbnail + title as one clickable target (opens that save's real Edit Item popup,
   weekPlanner.js's _renderLinkedSaveRow) — reset to look like plain content, not a button, so it
   reads the same as it did as a non-interactive row before this became clickable. */
.wp-card-modal-linked-open {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  border: none;
  background: none;
  padding: 0;
  text-align: left;
  cursor: pointer;
}
.wp-card-modal-linked-thumb {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  font-size: 16px;
}
.wp-card-modal-linked-title {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wp-card-modal-unlink-btn {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  background: none;
  color: var(--text-secondary, var(--text-primary));
  opacity: 0.6;
  cursor: pointer;
  font-size: 13px;
}
.wp-card-modal-unlink-btn:hover {
  opacity: 1;
  color: #e05252;
}
/* Lives in the header now (top right of the purple bar, same slot Save occupies in Edit mode —
   weekPlanner.js's markup already gives it the .purple-header-save-btn class for that shared
   look); nothing extra needed here beyond that shared rule. */

.wp-card-modal-footer {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}
.wp-card-modal-delete {
  width: 100%;
  padding: 9px 0;
  border-radius: 8px;
  border: 1px solid #e05252;
  background: none;
  color: #e05252;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s;
}
.wp-card-modal-delete:hover {
  background: #e05252;
  color: #fff;
}

/* ── save picker — a third small overlay (weekPlanner.js's _ensureSavePickerModal) stacking on
   top of the still-open card modal, its own dedicated .modal-overlay rather than a screen swapped
   into the card modal's own body. New classes throughout — not shared with embedBuilder.css's
   own (multi-select) picker, since that file isn't loaded on this page. ── */
.wp-save-picker-modal {
  width: 420px;
  padding: 24px;
  max-height: 70dvh;
}
.wp-save-picker-header h2 {
  margin: 0 0 14px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text-primary);
}
.wp-save-picker-search {
  width: 100%;
  padding: 10px 12px;
  border: 1.5px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
  outline: none;
  color: var(--text-primary);
  background: var(--surface);
  margin-bottom: 12px;
  flex-shrink: 0;
}
.wp-save-picker-search:focus {
  border-color: var(--primary);
}
.wp-save-picker-list-title {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  flex-shrink: 0;
}
.wp-save-picker-list {
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.wp-save-picker-empty {
  padding: 20px 0;
  text-align: center;
  font-size: 13px;
  color: var(--text-secondary, var(--text-primary));
  opacity: 0.7;
}
.wp-save-picker-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px;
  border-radius: 8px;
  cursor: pointer;
}
.wp-save-picker-row:hover {
  background: var(--primary-bg);
}
.wp-save-picker-thumb {
  width: 36px;
  height: 36px;
  border-radius: 6px;
  flex-shrink: 0;
  object-fit: cover;
  display: block;
}
.wp-save-picker-thumb--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
  color: rgba(255,255,255,0.9);
  background: linear-gradient(135deg, #5B5BEF 0%, #8B85F5 100%);
}
.wp-save-picker-row-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.wp-save-picker-row-title {
  min-width: 0;
  font-size: 14px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wp-save-picker-row-type {
  min-width: 0;
  font-size: 12px;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wp-save-picker-load-more {
  flex-shrink: 0;
  margin: 8px 0 2px;
  padding: 8px;
  border: none;
  border-radius: 8px;
  background: var(--primary-bg);
  color: var(--primary);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.wp-save-picker-load-more:hover {
  background: var(--primary-hover, var(--primary-bg));
}
