/* --------------------------------------------------- */
/*                  CARD FLOAT ACTIONS                 */
/* --------------------------------------------------- */
/* Shared between the tasks page's kanban cards and the homepage's
   read-only task-overview cards — see shared/scripts/taskCardActions.js. */
#card-float-actions {
  position: fixed;
  display: flex;
  flex-direction: column;
  gap: 5px;
  /* A fixed pixel offset, not a percentage of the widget's own (variable -
     depends on how many buttons are visible) height: button 1 (edit) is
     NEVER hidden, so the second visible button - whichever one that
     actually is in a given context (star, or duplicate when star itself
     is hidden in the done section) - always starts exactly 10px
     (padding-top) + 25px (button 1's own height) + 5px (gap) = 40px below
     the div's own untransformed top edge, so its center sits at
     40 + 12.5 (half of its own 25px height) = 52.5px below it, regardless
     of the widget's total height. Since _showCardFloatActions
     (taskCardActions.js) sets the div's own (untransformed) `top` to the
     card's real vertical center already, translateY(-52.5px) lands that
     fixed point exactly on the card's center every time, everywhere - a
     real kanban/task-section card included, per direct feedback. */
  transform: translateY(-52.5px);
  z-index: 100;
  padding: 10px 10px 10px 20px;
  pointer-events: none;
}
.card-float-btn {
  opacity: 0;
  transform: translateX(-6px) scale(0.85);
  /* opacity/transform are NOT transitioned here — the spawn-in motion is
     played explicitly via Element.animate() instead (_showCardFloatActions,
     taskCardActions.js), which always plays a fresh animation on every
     call. A CSS transition here would only replay when the browser detects
     an actual before/after style change across a rendered frame — reliably
     true for the very first hover (genuinely opacity:0 -> 1), but NOT for
     hovering directly from one card to an adjacent one with barely any
     gap: "visible" was already applied for the previous card, so the class
     re-added here is a no-op as far as the transition engine's concerned,
     and the animation silently never replayed. The hover-driven properties
     below (border-color/color/background-color) ARE real CSS transitions
     though, unlike that spawn-in motion - :hover already gives the browser
     a genuine before/after style change to animate between on its own,
     with no need for the same manual Element.animate() workaround. */
  transition:
    border-color 150ms,
    color 150ms,
    background-color 150ms;
  /* Same base "neutral action" blue phone's own quick-action buttons use
     at rest (--secondary-color, .phone-quick-action-btn, tasks/styles/
     editTask.css) - edit and duplicate both stay this color (duplicate
     never overrides it below, same as phone's own move-to-cell/reorder
     buttons sharing this identical base blue instead of getting their own
     accent) - .card-float-btn--star/--delete override it further down,
     matching phone's identical star/delete overrides one-for-one. */
  background: var(--secondary-color);
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 50%;
  width: 25px;
  height: 25px;
  min-width: 25px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: var(--cursor-pointer, pointer);
  color: #ffffff;
  font-size: 0.7em;
}
.card-float-btn--star {
  background: var(--highlight);
  color: #000000;
}
.card-float-btn--delete {
  background: var(--priority-one);
}
#card-float-actions.visible {
  background: radial-gradient(
    ellipse at center,
    rgba(0, 0, 0, 0.5) 0%,
    transparent 70%
  );
  pointer-events: auto;
}
/* Arc, not a straight column - the middle one sticks all the way out to
   the apex (translateX(0)), the ones around it tuck back in towards the
   card instead of lining up flush with it, so the whole stack reads as
   curving around the card's right corner rather than as a flat vertical
   strip; delete (always last, never hidden) curls further out still,
   continuing that same arc rather than just trailing off down the column.
   --arc-x/--arc-y are set on EACH button by _applyCardFloatArc
   (taskCardActions.js) - the ONE shared formula that computes every
   button's own slot from however many are actually visible right now
   (edit+star+duplicate+delete on a real kanban/task-section card; edit+
   duplicate+delete in the done section; edit+star+delete on the homepage's
   read-only overview cards) - see that function's own doc comment for the
   full reasoning. The fallbacks here only matter for the very first paint
   before any hover has ever run that function once. */
#card-float-actions.visible .card-float-btn {
  opacity: 1;
  transform: translate(var(--arc-x, -12px), var(--arc-y, 0px)) scale(1);
}
/* Hides a button for the current card's context (star in the done section,
   duplicate on the homepage's read-only overview cards) - a real class
   rather than each button's own inline style.display, so _applyCardFloatArc
   (taskCardActions.js) can query "which buttons are actually visible right
   now" directly off it. */
.card-float-btn--ctx-hidden {
  display: none;
}
/* Same "invert to a bright white fill with the button's own accent color"
   hover treatment phone's own quick-action buttons use on interaction
   (.phone-quick-action-btn.hovered, tasks/styles/editTask.css) - background
   flips to white, the icon/border pick up whichever accent that button's
   REST state (above) was already using as its background, so the two
   states read as a genuine color-swap rather than two unrelated looks.
   Scoped through #card-float-actions.visible (not a bare .card-float-btn:hover)
   so this can safely repeat the SAME translate(--arc-x, --arc-y) the
   spawn-in rule above already applies, just with a bigger scale layered on
   top of it - a bare :hover rule redeclaring only scale would otherwise
   silently reset the button back to its own untransformed default
   position, undoing _applyCardFloatArc's own per-button placement the
   instant the pointer entered it. */
#card-float-actions.visible .card-float-btn:hover {
  transform: translate(var(--arc-x, -12px), var(--arc-y, 0px)) scale(1.2);
}
.card-float-btn:hover {
  background: #ffffff;
  border-color: var(--secondary-color);
  color: var(--secondary-color);
}
.card-float-btn--star:hover {
  border-color: var(--highlight);
  color: var(--highlight);
}
/* Distinct danger tint on hover, unlike every other quick action - a
   destructive, irreversible-past-this-point action (even with its own
   confirmation dialog still standing between a hover and an actual
   delete) reads more safely when it doesn't blend into the same "just
   another action" highlight color as edit/star/duplicate. Same
   --priority-one red already used for an overdue-date accent elsewhere in
   this exact file, and phone's own identical .phone-quick-action-btn--delete.hovered. */
.card-float-btn--delete:hover {
  border-color: var(--priority-one);
  color: var(--priority-one);
}
/* No .card-float-btn .fa-solid.rotate color override here anymore - it used
   to tint the favorited star's icon gold, back when this button's own
   background was a neutral dark color (something worth calling out against
   it). Now that .card-float-btn--star's own background IS that same gold
   (matching phone's identical quick-action button, above), that override
   put a gold icon on a gold background - invisible - confirmed as a real,
   reported bug. The icon's own color (#000000, .card-float-btn--star's own
   rule above) already reads clearly against that gold background in
   either star state (hollow outline or solid/rotating), with nothing left
   for this rule to usefully add. */
/* --------------------------------------------------- */
/*                  FAVORITE (STAR)                    */
/* --------------------------------------------------- */
/* Toggled by setFavorite (tasks/scripts/tasks.js on the tasks page,
   scripts/taskReadPanel.js on the homepage) — same visual either way. */
.rotate {
  box-shadow: none;
  animation: rotate 4s linear infinite;
}
@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.task-card-container.active {
  outline: 1px solid var(--highlight);
}
/* Mirrors .link-container.found (styles.css) — the same "this is what the
   hovered panel row is pointing at" treatment findLinkStatsReference gives a
   real link, here for findTasksWorkspaceReference's own hover-connector line
   from a task-overview card to this exact card inside the embedded tasks
   workspace (scripts/taskOverviewContainer.js). Dashed rather than
   .active's plain solid outline so the two read distinctly if a card is
   ever both at once (currently open for reading AND being pointed at). */
.task-card-container.found {
  outline: 2px dashed var(--highlight);
  outline-offset: -2px;
}
/* Pulsing watermark glow - back on (kept the other card-level ideas below
   commented/removed instead). Base (always-on, non-animated) glow below is
   the same rule either way - this just layers the animation on top of it. */
.task-card-container:has(.fa-star.rotate) .card-category-watermark {
  animation: watermark-pulse-glow 1.6s ease-in-out infinite;
}
@keyframes watermark-pulse-glow {
  0%,
  100% {
    opacity: 0.55;
    scale: 1;
  }
  50% {
    opacity: 0.9;
    scale: 1.05;
  }
}
@media (prefers-reduced-motion: reduce) {
  .task-card-container:has(.fa-star.rotate) .card-category-watermark {
    animation: none;
  }
}
.task-card-container:has(.fa-star.rotate) .card-category-watermark {
  opacity: 0.75;
  text-shadow:
    0 0 3px var(--highlight),
    0 0 6px var(--highlight),
    0 0 12px var(--highlight),
    0 0 20px var(--highlight);
}
/* Registered so the browser can smoothly interpolate --snake-angle across
   the animation below — an unregistered custom property is just a string
   as far as animation is concerned, so conic-gradient's "from" angle would
   otherwise jump between keyframe values instead of sweeping through them. */
/*
@property --snake-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
*/
/* A glowing arc that continuously travels around the card's own edge while
   it's favorited — same trigger as the watermark glow above. Drawn with a
   single pseudo-element: the conic-gradient paints the whole padded box,
   then the mask punches out everything except a thin ring (the padding
   value below is that ring's thickness) — the classic gradient-border
   technique, rather than actually animating a border property (which
   can't take a gradient in the first place).
   COMMENTED OUT, not deleted - kept for an easy revert back to this look.
   See the "COMET ALTERNATIVE" block right below for what's active now. */
/*
.task-card-container:has(.fa-star.rotate)::after {
  content: "";
  position: absolute;
  // Right edge excluded (inset/padding both 0 there) — the category's own
  // border-right already lives there, so the ring would just double up
  // on top of it.
  inset: -3px 0 -3px -3px;
  border-radius: inherit;
  padding: 2px 0 2px 2px;
  background: conic-gradient(
    from var(--snake-angle),
    transparent 0deg,
    transparent 270deg,
    color-mix(in srgb, var(--highlight) 40%, transparent) 320deg,
    var(--highlight) 345deg,
    transparent 360deg
  );
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
  z-index: 1;
  animation: snake-glow-rotate 3s linear infinite;
}
@keyframes snake-glow-rotate {
  to {
    --snake-angle: 360deg;
  }
}
@media (prefers-reduced-motion: reduce) {
  .task-card-container:has(.fa-star.rotate)::after {
    animation: none;
  }
}
*/

/* === COMET ALTERNATIVE ===
   Undone (per feedback: a card-perimeter effect - moving box-shadow blur
   included - repaints across the WHOLE card's bounding area every frame,
   times up to 2 pseudo-elements, times however many cards are favorited at
   once - a real cost once that count gets into the 8-10 range, unlike the
   tiny fixed-size icon the STAR PULSE below animates instead).
   COMMENTED OUT, not deleted - see the ring above (also commented) and the
   active STAR PULSE below for the other two options this went through. */
/*
.task-card-container:has(.fa-star.rotate)::before,
.task-card-container:has(.fa-star.rotate)::after {
  content: "";
  position: absolute;
  top: -3px;
  left: -3px;
  width: 8px;
  height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: var(--highlight);
  offset-path: border-box;
  offset-distance: 0%;
  pointer-events: none;
  z-index: 1;
  animation: comet-orbit 3s linear infinite;
}
.task-card-container:has(.fa-star.rotate)::after {
  box-shadow:
    0 0 6px 2px var(--highlight),
    0 0 16px 5px color-mix(in srgb, var(--highlight) 55%, transparent);
}
.task-card-container:has(.fa-star.rotate)::before {
  width: 6px;
  height: 6px;
  opacity: 0.4;
  filter: blur(1.5px);
  animation-delay: 1500ms;
}
@keyframes comet-orbit {
  to {
    offset-distance: 100%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .task-card-container:has(.fa-star.rotate)::before,
  .task-card-container:has(.fa-star.rotate)::after {
    animation: none;
  }
}
*/

/* === STAR PULSE (active) ===
   Neither a ring nor a comet - no card-perimeter effect at all anymore, per
   feedback that surrounding the whole card wasn't necessary and that cost
   matters here (this can run on up to ~10 favorited cards simultaneously).
   Instead, just the star icon itself breathes - a slow scale+glow pulse,
   confined to a ~16px icon instead of a whole card's border.

   Cheap on purpose, in two ways: scale (below) is its own CSS property,
   distinct from transform - the star's EXISTING spin (.rotate above)
   already animates transform: rotate(...), and stacking a second transform-
   based animation on the same property would just fight/override it, not
   combine with it. Animating scale as its own property instead runs
   alongside the spin for free, both compositor-only work (no repaint) on
   their own. filter: drop-shadow's blur radius pulsing IS a real repaint
   (same cost class as the ring/comet's own box-shadow), but the repainted
   area is this one small icon's own box, not a whole card's - a fraction of
   a percent of the pixel cost the same technique had when it covered an
   entire card's perimeter, even multiplied by 10 simultaneous favorites. */
.fa-star.rotate {
  animation:
    rotate 4s linear infinite,
    star-pulse-glow 1.6s ease-in-out infinite;
}
@keyframes star-pulse-glow {
  0%,
  100% {
    scale: 1;
    filter: drop-shadow(0 0 2px var(--highlight));
  }
  50% {
    scale: 1.3;
    filter: drop-shadow(0 0 7px var(--highlight));
  }
}
@media (prefers-reduced-motion: reduce) {
  .fa-star.rotate {
    animation: none;
  }
}
/* === END STAR PULSE === */

/* === STATIC OUTLINE + GLOW (active) ===
   Stepping away from moving/animated card-perimeter effects entirely -
   every one tried (the original ring, comet, tapering tail, multi-dot
   train) either cost too much or just didn't look right. This is about as
   simple as a card-level treatment gets: a steady, non-animated outline in
   the same highlight color as the star/watermark pulses above, matching
   the same convention .active/.found already use elsewhere in this file
   for other card states - plus a soft static glow behind it for some
   warmth/depth, added purely for looks now that nothing here needs to
   avoid box-shadow specifically anymore. The performance concern earlier
   was always about ANIMATING box-shadow/filter every frame (a real,
   continuous repaint cost) - a shadow that's simply set once and left alone
   is exactly as cheap as any other static style, painted once when a task
   is favorited/unfavorited and never touched again regardless of how many
   cards are favorited at once. outline (not border) so it never affects
   the card's own layout/box size the way changing border-width would. */
.task-card-container:has(.fa-star.rotate) {
  outline: 1px solid var(--highlight);
  outline-offset: 2px;
  box-shadow: 0 0 18px 3px color-mix(in srgb, var(--highlight) 65%, transparent);
}
/* === END STATIC OUTLINE + GLOW === */

/* Outline + glow for an overdue card - COMMENTED OUT for now (not deleted)
   to try the corner-peek square below instead. Same static mechanism as
   the favorited star's own rule above, just in --priority-one instead of
   --highlight. */
/*
.task-card-container:not(.done):not(:has(.fa-star.rotate)):has(
    .card-date.alert
  ) {
  outline: 1px solid var(--priority-one);
  outline-offset: 2px;
  box-shadow: 0 0 14px 2px
    color-mix(in srgb, var(--priority-one) 65%, transparent);
}
*/
/* Attempt: a corner "bracket" overlay instead of trying to sit behind the
   card - a transparent 20x20 box, in FRONT (a plain pseudo-element, no
   z-index tricks needed this time - there's no "child can never paint
   below its own parent's background" limitation to fight when this is
   simply drawn on top, which is exactly what the previous behind-the-card
   square attempt ran into and couldn't get around without real DOM
   restructuring). border-radius: inherit copies the card's own actual
   radius (taskCard.css) onto this same-origin, same-size corner box, so
   its rounded corner traces exactly along the card's own real rounded
   edge instead of overflowing past it - only border-top/border-left are
   set (border-right/bottom left at their default none), so the visible
   result reads as a red bracket hugging just the top-left corner, not a
   full outline. pointer-events: none so it never intercepts clicks/hover
   meant for the real card underneath it.
   z-index: 2, not auto/omitted - styles/desktopPanels.css's own
   ".task-card-container > *:not(...)" rule stamps z-index: 1 on
   essentially every REAL child (name/tags/date row/...), which otherwise
   outranks this pseudo-element's default z-index: auto regardless of paint
   order - confirmed as the actual, reported cause of this being completely
   invisible rather than just partially covered.
   Not excluded for a favorited card anymore, unlike the outline+glow/
   watermark-glow alert rules above - those lived on the same shared visual
   slot (::after, or the container's own outline/box-shadow) the favorited
   star's own gold version already used, so both could never show at once
   either way. This bracket has no such conflict (::before is untouched by
   any of that), so a task that's both overdue AND favorited now gets the
   gold star treatment plus this red corner bracket together, requested
   explicitly rather than assumed. */
.task-card-container:not(.done):has(.card-date.alert)::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 20px;
  height: 20px;
  border-radius: inherit;
  border-top: 2px solid var(--priority-one);
  border-left: 2px solid var(--priority-one);
  /* Offset toward top-left (negative x/y), not centered like the outline's
     own box-shadow above was - a box-shadow with no offset spreads evenly
     on all 4 sides regardless of which borders are actually set, so a
     centered one here would glow the (border-less) right/bottom edges of
     this tiny box just as much as the top/left ones the bracket actually
     draws. Shifting the shadow's own origin toward top-left concentrates
     it there instead, fading out before it reaches the other two sides -
     just a test for now. */
  box-shadow: -3px -3px 14px 2px
    color-mix(in srgb, var(--priority-one) 65%, transparent);
  z-index: 2;
  pointer-events: none;
}

/* Same base (non-animated) watermark glow the favorited star gets
   (:has(.fa-star.rotate) .card-category-watermark below), just in
   --priority-one instead of --highlight, and deliberately without that
   rule's own watermark-pulse-glow animation layered on top - asked for
   explicitly as "the glow, not the pulse" this time, unlike every other
   accent in this file so far. Only ever on a card that ISN'T also
   favorited, same as the (currently commented out) outline+glow above. */
.task-card-container:not(.done):not(:has(.fa-star.rotate)):has(.card-date.alert)
  .card-category-watermark {
  opacity: 0.55;
  text-shadow:
    0 0 2px var(--priority-one),
    0 0 4px var(--priority-one),
    0 0 10px var(--priority-one),
    0 0 18px var(--priority-one);
}
/* --------------------------------------------------- */
/*                  CHECKBOX PROGRESS                  */
/* --------------------------------------------------- */
/* Built by buildCheckboxProgress (shared/scripts/taskCheckboxProgress.js) —
   same bar on the tasks page's own kanban cards and the homepage's
   read-only overview cards. */
.card-progress-container {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 6px;
}
.card-progress-bar {
  flex: 1;
  height: 4px;
  background: var(--font-color-weak, #444);
  border-radius: 2px;
  overflow: hidden;
}
.card-progress-fill {
  height: 100%;
  border-radius: 2px;
  transition: width 300ms ease;
}
.card-progress-label {
  font-size: 0.75em;
  color: var(--font-color-clear);
  white-space: nowrap;
  min-width: 26px;
  text-align: right;
  font-weight: normal;
}
