/* ==========================================================================
   TIO Bulk Optimize - Component Library
   --------------------------------------------------------------------------
   BEM blocks used by the Bulk Optimize admin page. All rules are scoped
   under .tio-wrap so nothing leaks into the surrounding WP admin chrome,
   EXCEPT the modal block which is appended to document.body.

   All measurements (font sizes, line-heights, padding, gaps, borders,
   radii, colours) are copied verbatim from the locked Figma design system
   so the rendered UI matches the design pixel-true. Cross-reference:
     - Nav         Figma node 306:9821
     - Alert       Figma node 166:4006
     - Progress    Figma node 307:894
     - Stat card   Figma node 306:10481
     - Tag (top)   Figma node 306:9796
   ========================================================================== */


/* --- Tokens (Figma source of truth) ------------------------------------- */

.tio-wrap {
  /* Colours — exact hex from the tokens variable_defs response */
  --tio-c-primary:               #30d9cc;
  --tio-c-primary-container:     #e9fbfa;
  --tio-c-secondary:             #ffc733;
  --tio-c-secondary-container:   #fff8e5;
  --tio-c-error:                 #d00101;
  --tio-c-error-container:       #fff3f3;
  --tio-c-on-surface:            #1e293b;
  --tio-c-on-surface-alt:        #334155;
  --tio-c-on-secondary:          #000000;
  --tio-c-surface:               #f8fafc;
  --tio-c-surface-container:     #e2e8f0;
  --tio-c-outline:               #475569;
  --tio-c-state-on-surface-08:   rgba(30, 41, 59, 0.08);
  --tio-c-white:                 #ffffff;

  /* Typography — token name maps 1:1 with Figma styles */
  --tio-ff-display:              "Dela Gothic One", "Roboto Slab", Georgia, serif;
  --tio-ff-label:                "Dela Gothic One", "Roboto Slab", Georgia, serif;
  --tio-ff-body:                 "Roboto Slab", Georgia, serif;

  /* Spacing scale — only the values we actually use here */
  --tio-sp-1:  4px;
  --tio-sp-2:  8px;
  --tio-sp-3:  12px;
  --tio-sp-4:  16px;
  --tio-sp-5:  20px;
  --tio-sp-6:  24px;
  --tio-sp-8:  32px;

  /* Radii from Figma component specs */
  --tio-rad-tag:    4px;
  --tio-rad-card:   8px;
  --tio-rad-pill:   360px;

  /* Progress preview override target */
  --progress-pct: 0%;
}


/* --- Headings + container typography ------------------------------------ */
/* Per Figma:
   - h1 "The Image Optimizer" : display style (Dela Gothic One 32 / 40)
   - h2 section titles        : body-lg Bold (Roboto Slab 20 / 32, weight 700) */

.tio-wrap h1,
.tio-wrap .tio-page-title {
  font-family: var(--tio-ff-display);
  font-weight: 400;
  font-size: 32px;
  line-height: 40px;
  letter-spacing: 0;
  color: var(--tio-c-on-surface);
  margin: 0 0 var(--tio-sp-8) 0;
}

.tio-wrap h2,
.tio-wrap .tio-section-title {
  font-family: var(--tio-ff-body);
  font-weight: 700;
  font-size: 20px;
  line-height: 32px;
  letter-spacing: 0;
  color: var(--tio-c-on-surface);
  margin: 0;
}

/* Body intro paragraph under each section heading */
.tio-wrap .tio-body-md {
  font-family: var(--tio-ff-body);
  font-weight: 400;
  font-size: 16px;
  line-height: 24px;
  letter-spacing: 0;
  color: var(--tio-c-on-surface-alt);
  margin: 0;
}


/* --- Alert -------------------------------------------------------------- */
/* 2px solid border + 8px radius + 16/24 padding + 12px gap + 24px icon. */

.tio-wrap .tio-alert {
  display: flex;
  flex-direction: column;
  gap: var(--tio-sp-3);
  padding: var(--tio-sp-4) var(--tio-sp-6);
  border: 2px solid var(--tio-c-primary);
  border-radius: var(--tio-rad-card);
  background-color: var(--tio-c-primary-container);
  font-family: var(--tio-ff-body);
  color: var(--tio-c-on-surface);
}

.tio-wrap .tio-alert--info,
.tio-wrap .tio-alert--success {
  border-color: var(--tio-c-primary);
  background-color: var(--tio-c-primary-container);
}

.tio-wrap .tio-alert--warning {
  border-color: var(--tio-c-secondary);
  background-color: var(--tio-c-secondary-container);
}

.tio-wrap .tio-alert--error {
  border-color: var(--tio-c-error);
  background-color: var(--tio-c-error-container);
}

.tio-wrap .tio-alert__header {
  display: flex;
  align-items: center;
  gap: var(--tio-sp-3);
}

.tio-wrap .tio-alert__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 14px;
  font-weight: 700;
  font-family: var(--tio-ff-body);
  background-color: var(--tio-c-primary);
  color: var(--tio-c-on-surface);
  flex-shrink: 0;
}

.tio-wrap .tio-alert--warning .tio-alert__icon {
  background-color: var(--tio-c-secondary);
  color: var(--tio-c-on-secondary);
}

.tio-wrap .tio-alert--error .tio-alert__icon {
  background-color: var(--tio-c-error);
  color: var(--tio-c-white);
}

.tio-wrap .tio-alert__title {
  margin: 0;
  font-family: var(--tio-ff-body);
  font-weight: 700;
  font-size: 16px;
  line-height: 24px;
  color: var(--tio-c-on-surface);
}

.tio-wrap .tio-alert__body {
  margin: 0;
  font-family: var(--tio-ff-body);
  font-weight: 400;
  font-size: 16px;
  line-height: 24px;
  color: var(--tio-c-on-surface);
}

.tio-wrap .tio-alert__cta {
  margin-top: var(--tio-sp-1);
}


/* --- Button danger variant --------------------------------------------- */

.tio-wrap .tio-button--danger {
  background-color: var(--tio-c-error);
  border-color: var(--tio-c-error);
  color: var(--tio-c-white);
}

.tio-wrap .tio-button--danger:hover {
  background-color: color-mix(in srgb, var(--tio-c-error) 88%, #000);
  border-color: color-mix(in srgb, var(--tio-c-error) 88%, #000);
}

.tio-wrap .tio-button--danger:disabled,
.tio-wrap .tio-button--danger.is-disabled {
  background-color: color-mix(in srgb, var(--tio-c-error) 40%, #fff);
  border-color: transparent;
  cursor: not-allowed;
}

/* Loading state — keep the button's disabled palette so it reads as
   "primary intent, busy, not interactive" rather than fully active.
   Just lay the label + 20px trailing spinner out with an 8px gap. */
.tio-wrap .tio-button.is-loading {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: progress;
}

.tio-wrap .tio-button__spinner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
}

@keyframes tio-spin {
  to { transform: rotate(360deg); }
}

.tio-wrap .tio-spin {
  animation: tio-spin 0.9s linear infinite;
  transform-origin: center;
  display: inline-flex;
}

@media (prefers-reduced-motion: reduce) {
  .tio-wrap .tio-spin { animation: none; }
}


/* --- Modal (lives outside .tio-wrap, appended to body) ----------------- */
/* JS appends the modal wrapped in .tio-wrap so its button styles match,
   but the modal positioning itself must work without the parent scope. */

.tio-modal {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tio-modal[hidden] { display: none; }

.tio-modal__backdrop {
  position: absolute;
  inset: 0;
  background-color: rgba(15, 23, 42, 0.5);
}

.tio-modal__panel {
  position: relative;
  width: 100%;
  max-width: 480px;
  margin: 16px;
  padding: 32px;
  background-color: #ffffff;
  border-radius: 8px;
  box-shadow: 0 24px 48px rgba(15, 23, 42, 0.25);
  display: flex;
  flex-direction: column;
  gap: 16px;
  font-family: "Roboto Slab", Georgia, serif;
}

.tio-modal__title {
  margin: 0;
  font-size: 18px;
  line-height: 24px;
  font-weight: 700;
  color: #1e293b;
}

.tio-modal__body {
  margin: 0;
  font-size: 16px;
  line-height: 24px;
  color: #334155;
}

.tio-modal__actions {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 8px;
}


/* --- Nav (settings <-> bulk optimize tab strip) ------------------------- */
/* Per Figma 306:9821: pill container, rgba(30,41,59,0.08) bg, 24px H pad,
   4px V pad, 360px radius, 24px gap. Items: Dela Gothic One 16/16.
   Active item gets a 6.5px tall bar at bottom -3px in primary color. */

.tio-wrap .tio-nav {
  display: inline-flex;
  align-items: center;
  gap: var(--tio-sp-6);
  padding: var(--tio-sp-1) var(--tio-sp-6);
  background-color: var(--tio-c-state-on-surface-08);
  border-radius: var(--tio-rad-pill);
  margin: 0 0 var(--tio-sp-8) 0;
}

.tio-wrap .tio-nav__item {
  position: relative;
  display: inline-flex;
  align-items: center;
  font-family: var(--tio-ff-label);
  font-weight: 400;
  font-size: 16px;
  line-height: 16px;
  letter-spacing: 0;
  color: var(--tio-c-on-surface-alt);
  text-decoration: none;
  padding: var(--tio-sp-4) 0;
  transition: color 120ms ease;
}

.tio-wrap .tio-nav__item:hover,
.tio-wrap .tio-nav__item:focus {
  color: var(--tio-c-on-surface);
  text-decoration: none;
  box-shadow: none;
  outline: none;
}

.tio-wrap .tio-nav__item--active {
  color: var(--tio-c-on-surface);
}

.tio-wrap .tio-nav__item--active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 9px;
  height: 6.5px;
  background-color: var(--tio-c-primary);
  border-radius: 1px;
}


/* --- Progress ---------------------------------------------------------- */
/* Per Figma 307:894: surface bg, 24px padding, 8px radius, 16px vertical gap.
   The bar is a 56px-tall primary-container box with a 2px primary border.
   The fill overlaps the border (left:-2px top:-2px) so when it reaches 100%
   it fully covers the bar. Preview is a 48px square (4px radius, 1px white
   border) absolutely positioned at the leading edge of the fill via the
   --progress-pct custom property. */

.tio-wrap .tio-progress {
  display: flex;
  flex-direction: column;
  gap: var(--tio-sp-4);
  padding: var(--tio-sp-6);
  background-color: var(--tio-c-surface);
  border-radius: var(--tio-rad-card);
  overflow: hidden;
}

.tio-wrap .tio-progress__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tio-sp-2);
  font-family: var(--tio-ff-body);
}

.tio-wrap .tio-progress__header-left {
  display: inline-flex;
  align-items: center;
  gap: var(--tio-sp-2);
}

.tio-wrap .tio-progress__caption {
  font-family: var(--tio-ff-body);
  font-weight: 400;
  font-size: 14px;
  line-height: 20px;
  color: var(--tio-c-on-surface);
}

.tio-wrap .tio-progress__refresh {
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--tio-c-primary);
  border: none;
  background: transparent;
  cursor: pointer;
}

.tio-wrap .tio-progress__bar {
  position: relative;
  height: 56px;
  background-color: var(--tio-c-primary-container);
  border: 2px solid var(--tio-c-primary);
  border-radius: var(--tio-rad-card);
  overflow: hidden;
}

.tio-wrap .tio-progress__fill {
  position: absolute;
  top: -2px;
  bottom: -2px;
  left: -2px;
  width: calc(var(--progress-pct, 0%) + 2px);
  background-color: var(--tio-c-primary);
  /* Round all four corners so the fill sits inside the bar's rounded
     shape at 0%, at 100%, and at every percentage in between. */
  border-radius: var(--tio-rad-card);
  transition: width 600ms ease-out;
  z-index: 1;
}

/* Paused variant — swap to yellow palette per Figma node 307:977. The bar,
   border, and fill all shift to the secondary container/secondary tokens
   so the user immediately reads "this is sitting still on purpose". */
.tio-wrap .tio-progress--paused .tio-progress__bar {
  background-color: var(--tio-c-secondary-container);
  border-color: var(--tio-c-secondary);
}

.tio-wrap .tio-progress--paused .tio-progress__fill {
  background-color: var(--tio-c-secondary);
}

/* Header pause icon inherits the secondary colour so the filled circle
   reads as the same yellow as the bar/border. */
.tio-wrap .tio-progress--paused .tio-progress__refresh {
  color: var(--tio-c-secondary);
}

/* Nothing is moving while paused, so freeze the preview's shimmer. */
.tio-wrap .tio-progress--paused .tio-progress__preview {
  animation: none;
}

.tio-wrap .tio-progress__preview {
  position: absolute;
  top: 50%;
  /* Preview is 48x48 sitting inside the 56px-tall bar with a 4px gap
     all around at its base size — that means right edge 4px inside
     the fill's leading edge (vertically 4px top + 4px bottom via the
     translate -50%). Shimmer animation scales from that base. At low
     fill percentages the bar's overflow:hidden clips gracefully. */
  right: calc(100% - var(--progress-pct, 0%) + 4px);
  width: 48px;
  height: 48px;
  transform: translateY(-50%);
  border-radius: 4px;
  border: 1px solid var(--tio-c-white);
  object-fit: cover;
  background-color: var(--tio-c-surface-container);
  transition: right 600ms ease-out;
  z-index: 2;
  animation: tio-shimmer 1.6s ease-in-out infinite;
}

@keyframes tio-shimmer {
  0%, 100% { transform: translateY(-50%) scale(1);    filter: brightness(1); }
  50%      { transform: translateY(-50%) scale(1.06); filter: brightness(1.12); }
}

@media (prefers-reduced-motion: reduce) {
  .tio-wrap .tio-progress__preview { animation: none; }
  .tio-wrap .tio-progress__fill    { transition: none; }
}

.tio-wrap .tio-progress__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--tio-sp-2);
  font-family: var(--tio-ff-body);
  font-size: 14px;
  line-height: 20px;
}

.tio-wrap .tio-progress__current {
  color: var(--tio-c-on-surface-alt);
  max-width: 60ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tio-wrap .tio-progress__eta {
  color: var(--tio-c-on-surface);
  flex-shrink: 0;
}

/* "Estimating..." cycles 1 → 2 → 3 dots so the label feels alive while
   the runner is still gathering enough tick samples for a real number.
   First dot is always visible; second and third fade in on cue. The
   container reserves the dot strip's max width so the surrounding flex
   layout doesn't jitter as dots blink in and out. */
.tio-wrap .tio-eta-dots {
  display: inline-block;
  width: 1.5ch;
  text-align: left;
}

.tio-wrap .tio-eta-dots > span:nth-child(2) {
  animation: tio-eta-dot-from-33 1.2s linear infinite;
  opacity: 0;
}

.tio-wrap .tio-eta-dots > span:nth-child(3) {
  animation: tio-eta-dot-from-66 1.2s linear infinite;
  opacity: 0;
}

@keyframes tio-eta-dot-from-33 {
  0%, 32%   { opacity: 0; }
  33%, 100% { opacity: 1; }
}

@keyframes tio-eta-dot-from-66 {
  0%, 65%   { opacity: 0; }
  66%, 100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .tio-wrap .tio-eta-dots > span { animation: none; opacity: 1; }
}


/* --- Stats grid + stat card -------------------------------------------- */
/* Per Figma 306:10481: stat cards are surface-container bg (#e2e8f0), NO
   border, 8px radius, 24px padding, 16px vertical gap. Value text is
   Dela Gothic One 32/40 black. Hint is body-sm 14/20 on-surface-alt. */

.tio-wrap .tio-stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--tio-sp-6);
}

@media (min-width: 1000px) {
  /* The Start screen uses 2x2 (Remaining/Optimized then Skipped/Total).
     Running screen also fits naturally in 2x2. No need for 3-col. */
}

@media (max-width: 600px) {
  .tio-wrap .tio-stats-grid { grid-template-columns: 1fr; }
}

.tio-wrap .tio-stat-card {
  display: flex;
  flex-direction: column;
  gap: var(--tio-sp-4);
  padding: var(--tio-sp-6);
  background-color: transparent;
  border: 2px solid var(--tio-c-surface-container);
  border-radius: var(--tio-rad-card);
}

/* The leading card on a multi-card row (UNOPTIMIZED on Start, DONE on
   Running, etc.) uses the primary-container teal tint per Figma to
   draw the eye to the metric the user is acting on. */
.tio-wrap .tio-stat-card--highlight {
  background-color: var(--tio-c-primary-container);
  border-color: transparent;
}

.tio-wrap .tio-stat-card__value {
  font-family: var(--tio-ff-display);
  font-weight: 400;
  font-size: 32px;
  line-height: 40px;
  letter-spacing: 0;
  color: #000000;
  margin: 0;
}

.tio-wrap .tio-stat-card__hint {
  font-family: var(--tio-ff-body);
  font-weight: 400;
  font-size: 14px;
  line-height: 20px;
  color: var(--tio-c-on-surface-alt);
  margin: 0;
}


/* --- Tag (3 variants) -------------------------------------------------- */
/* Caption typography: Roboto Slab 14/16, letter-spacing 1px, UPPERCASE.
   Three colour treatments, all share padding 4px/6px and 4px radius:
     - default / "page heading" tag    : secondary yellow bg, black text
     - dark (stat-card labels, prog %) : on-surface bg, surface text
     - neutral (Media Library Skipped) : surface-container bg, slate text  */

.tio-wrap .tio-tag,
.tio-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 6px;
  border-radius: var(--tio-rad-tag);
  font-family: var(--tio-ff-body);
  font-weight: 400;
  font-size: 14px;
  line-height: 16px;
  letter-spacing: 1px;
  text-transform: uppercase;
  white-space: nowrap;
  background-color: var(--tio-c-secondary, #ffc733);
  color: var(--tio-c-on-secondary, #000000);
}

.tio-wrap .tio-tag--dark {
  background-color: var(--tio-c-on-surface);
  color: var(--tio-c-surface);
}

.tio-wrap .tio-tag--neutral,
.tio-tag--neutral {
  background-color: var(--tio-c-surface-container, #e2e8f0);
  color: var(--tio-c-on-surface-alt, #334155);
}

.tio-wrap .tio-tag--running   { background-color: var(--tio-c-primary);   color: var(--tio-c-on-surface); }
.tio-wrap .tio-tag--paused    { background-color: var(--tio-c-secondary); color: var(--tio-c-on-secondary); }
.tio-wrap .tio-tag--success   { background-color: var(--tio-c-primary);   color: var(--tio-c-on-surface); }
.tio-wrap .tio-tag--warning   { background-color: var(--tio-c-secondary); color: var(--tio-c-on-secondary); }
.tio-wrap .tio-tag--error     { background-color: var(--tio-c-error);     color: var(--tio-c-white); }


/* --- Misc utilities used by the JS templates --------------------------- */

.tio-wrap .tio-intro {
  display: flex;
  flex-direction: column;
  gap: var(--tio-sp-3);
  margin: 0;
}

/* The bulk-page canvas — white card with a 2px outline that wraps the
   whole bulk view body (everything below the nav strip). Children stack
   with a 24px flex gap; child blocks must NOT carry their own top/bottom
   margins (those would compound with the gap). Named .tio-bulk-canvas
   (NOT .tio-widget) so it doesn't clash with the existing settings-page
   widget styles in nctio-admin.css. */
.tio-wrap .tio-bulk-canvas {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--tio-sp-6);
  padding: var(--tio-sp-6);
  background-color: var(--tio-c-white);
  border: 2px solid var(--tio-c-outline);
  border-radius: 16px;
  max-width: 800px;
  box-sizing: border-box;
}

.tio-wrap .tio-divider {
  height: 2px;
  border: 0;
  background-color: var(--tio-c-outline);
  margin: 0;
  width: 100%;
}

.tio-wrap .tio-help {
  display: inline-flex;
  align-items: center;
  gap: var(--tio-sp-2);
  margin: 0;
  font-family: var(--tio-ff-body);
  font-size: 14px;
  line-height: 20px;
  color: var(--tio-c-on-surface-alt);
}

.tio-wrap .tio-help__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: var(--tio-c-on-surface);
  color: var(--tio-c-white);
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
}

.tio-wrap .tio-button-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--tio-sp-4);
  margin: 0;
}

/* Section heading + body intro block (above the divider). The widget
   controls the gap to the next sibling, so no margins of our own. */
.tio-wrap .tio-section-head {
  display: flex;
  flex-direction: column;
  gap: var(--tio-sp-3);
  margin: 0;
}

.tio-wrap .tio-section-head__tag {
  align-self: flex-start;
  margin: 0;
}
