/* ==========================================================================
   Components - Buttons, Cards, Forms, Modals, Toast
   Loaded by: ALL pages.
   Shared UI primitives used across the entire app. Do not add page-specific
   rules here — those belong in the page's own stylesheet.
   ========================================================================== */

/* ==========================================================================
   Cards
   .card is the base glass-morphism surface. Used directly or extended by
   .cal-card, .side-card, .chart-card, .apps-card, etc. on each page.
   ========================================================================== */

.card {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.045));
  border: 1px solid var(--border2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-soft);
}

/* ==========================================================================
   Buttons
   .btn is the base interactive button. Modifier classes change its color
   role (.primary, .danger, .ghost) or size (.sm). .icon-btn is a square
   icon-only button variant.
   ========================================================================== */

.btn {
  height: 42px;
  padding: 0 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-weight: 800;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  user-select: none;
  white-space: nowrap;
}

.btn:hover {
  background: rgba(255, 255, 255, 0.09);
}

/* Primary CTA — teal gradient. Used for "Save", "New Application", etc. */
.btn.primary {
  border: 1px solid rgba(0, 0, 0, 0.28);
  background: linear-gradient(180deg, rgba(45, 189, 177, 0.95), rgba(45, 189, 177, 0.82));
  color: rgba(6, 22, 20, 0.95);
  box-shadow: 0 10px 18px rgba(0, 0, 0, 0.25);
}

.btn.primary:hover {
  filter: brightness(1.03);
}

/* Danger — red tint for destructive actions like "Delete" */
.btn.danger {
  background: rgba(200, 95, 82, 0.16);
  border-color: rgba(200, 95, 82, 0.35);
}

.btn.danger:hover {
  background: rgba(200, 95, 82, 0.22);
}

/* Ghost — transparent background, border only visible via base .btn rule */
.btn.ghost {
  background: transparent;
}

/* Disabled state — shared across all button variants */
.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Small variant — shorter height, less padding. Used in table rows. */
.btn.sm {
  height: 36px;
  border-radius: 12px;
  padding: 0 12px;
  font-weight: 800;
}

/* Square icon button (e.g. month prev/next controls in calendar) */
.icon-btn {
  height: 40px;
  width: 44px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  cursor: pointer;
  font-weight: 900;
}

.icon-btn:hover {
  background: rgba(255, 255, 255, 0.08);
}

/* ==========================================================================
   Form Elements
   Shared input/select/textarea base styles. All inputs get the same dark
   translucent background and teal focus ring.
   ========================================================================== */

input[type="text"],
input[type="url"],
input[type="email"],
input[type="password"],
input[type="date"],
input[type="time"],
select,
textarea {
  width: 100%;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  background: rgba(0, 0, 0, 0.18);
  color: rgba(255, 255, 255, 0.92);
  padding: 10px 10px;
  outline: none;
}

textarea {
  resize: vertical;
  min-height: 160px;
}

/* ==========================================================================
   Notes Expand Button
   Appears below #notesInput in applications.html to expand/collapse the
   textarea height.
   DEPENDENCY: JavaScript in applications.js targets:
     - #expandNotesBtn   (the button)
     - .notes-wrap       (wrapper positioning context)
     - #notesInput       (the textarea)
     - .notes-expanding  (CSS class applied during height transition)
   Changing any of these IDs or class names requires updating JS and HTML too.
   ========================================================================== */

/* Wrapper that positions the expand button relative to the textarea */
.notes-wrap {
  position: relative;
  margin-bottom: 10px;
}

/* Circular expand/collapse toggle centered below the textarea */
.expand-btn {
  position: absolute;
  bottom: -13px;
  left: 50%;
  transform: translateX(-50%);
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(45, 189, 177, 0.14);
  border: 1px solid rgba(45, 189, 177, 0.38);
  color: rgba(45, 189, 177, 0.9);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  overflow: hidden;
  transition: background 0.2s ease, border-color 0.2s ease;
}

.expand-btn svg {
  width: 12px;
  height: 12px;
  flex: none;
  pointer-events: none;
  transition: transform 0.3s cubic-bezier(0.34, 1.4, 0.64, 1);
}

/* Rotate chevron 180° when expanded */
.expand-btn.is-expanded svg {
  transform: rotate(180deg);
}

/* Pulse only activates when JS detects the textarea content is near/past the visible boundary.
   JS adds .is-overflowing on input; removes it when content fits again. */
.expand-btn.is-overflowing {
  animation: notes-pulse 2.2s ease-in-out infinite;
}

/* Once expanded: stop pulsing and disable the hover glimmer.
   Both resume naturally when the modal closes and reopens (JS removes .is-expanded on openModal). */
.expand-btn.is-expanded {
  animation: none;
}

.expand-btn.is-expanded:hover::after {
  animation: none;
}

/* Pulsing teal glow to attract user attention to the expand affordance */
@keyframes notes-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(45, 189, 177, 0.38); }
  50%       { box-shadow: 0 0 0 6px rgba(45, 189, 177, 0); }
}

/* Glimmer sweep on hover — shimmer light passes across the button */
.expand-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(
    105deg,
    transparent 30%,
    rgba(255, 255, 255, 0.38) 50%,
    transparent 70%
  );
  background-size: 200% 100%;
  background-position: -100% center;
  pointer-events: none;
}

.expand-btn:hover {
  background: rgba(45, 189, 177, 0.22);
  border-color: rgba(45, 189, 177, 0.6);
}

.expand-btn:hover::after {
  animation: glimmer-sweep 0.5s ease forwards;
}

@keyframes glimmer-sweep {
  from { background-position: -100% center; }
  to   { background-position: 200% center; }
}

/* Applied programmatically by JS during the expand/collapse height animation.
   The JS adds this class before setting style.height, then removes it on
   transitionend so the textarea can resume manual resize. */
#notesInput.notes-expanding {
  transition: height 0.38s cubic-bezier(0.34, 1.15, 0.64, 1);
}

/* Teal focus ring shared across all inputs */
input:focus,
select:focus,
textarea:focus {
  border-color: rgba(45, 189, 177, 0.45);
  box-shadow: 0 0 0 3px rgba(45, 189, 177, 0.12);
}

input::placeholder {
  color: rgba(255, 255, 255, 0.65);
}

/* Dark calendar picker icon on date inputs */
input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(1);
  opacity: 0.9;
}

label {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.55);
  font-weight: 700;
}

/* .field wraps a label + input pair in a vertical stack */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ==========================================================================
   Chips & Pills
   .chip is a colored status badge. Class names MUST match DB status values:
     applied | interviewing | offer | rejected | pending
   If you add a new status in the database, add a corresponding .chip rule here
   and in dashboard.js / applications.js chipClass() functions.

   NOTE: calendar.css and settings.css previously overrode the shared .grid
   class from this file. They now use .cal-grid and .settings-grid respectively
   to avoid collisions with the 2-column form grid defined here.
   ========================================================================== */

.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 800;
}

/* .turq and .applied share the same background — applied maps to teal-ish */
.chip.turq,
.chip.applied {
  background: rgba(152, 215, 239, 0.35);
}

.chip.blue {
  background: rgba(152, 215, 239, 0.35);
}

.chip.red,
.chip.rejected {
  background: rgba(224, 122, 79, 0.45);
}

.chip.interviewing {
  background: rgba(47, 209, 191, 0.35);
}

.chip.offer {
  background: rgba(107, 196, 123, 0.35);
}

.chip.pending {
  background: rgba(255, 196, 70, 0.22);
}

/* .pill is a neutral tag/count badge — used for filter counts, event counts */
.pill {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.74);
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(0, 0, 0, 0.18);
  padding: 6px 10px;
  border-radius: 999px;
  white-space: nowrap;
}

/* ==========================================================================
   Modal
   Full-screen backdrop + centered dialog. At ≤480px it becomes a bottom sheet.
   z-index: 60 — above the sidebar (z-index: 50) but below toasts (z-index: 80).
   ========================================================================== */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 18px;
  z-index: 60;
}

/* .show class toggled by JS to display:flex the backdrop */
.modal-backdrop.show {
  display: flex;
}

.modal {
  width: min(720px, 100%);
  border-radius: 18px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: linear-gradient(180deg, #1a2438, #131b2c);
  box-shadow: var(--shadow);
  overflow: hidden;
}

/* Header bar with title and close button */
.modal-top {
  padding: 14px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.modal-top h4 {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.86);
  margin: 0;
  font-weight: 800;
  letter-spacing: 0.2px;
}

.modal-body {
  padding: 14px 16px 16px;
}

/* Footer bar with action buttons */
.modal-actions {
  padding: 12px 16px 14px;
  display: flex;
  justify-content: space-between;
  gap: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(0, 0, 0, 0.08);
}

.modal-actions .right {
  display: flex;
  gap: 10px;
  align-items: center;
}

/* 2-column form layout used inside modals (e.g. Company/Role side by side).
   NOTE: calendar.css defines .cal-grid for its 7-column day grid.
         settings.css defines .settings-grid for its 2-column card layout.
   Neither overrides this rule — they use distinct class names to avoid conflict. */
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* Helper text below form fields */
.hint {
  margin-top: 8px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.6);
}

/* ==========================================================================
   Toast
   Fixed notification that auto-dismisses after ~2.5s. Appears bottom-right.
   z-index: 80 — above modals (z-index: 60).
   ========================================================================== */

.toast {
  position: fixed;
  right: 16px;
  bottom: 16px;
  width: min(360px, calc(100% - 32px));
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: linear-gradient(180deg, #1a2438, #131b2c);
  box-shadow: var(--shadow);
  padding: 12px 12px 12px;
  display: none;
  gap: 8px;
  z-index: 80;
}

/* .show class added by showToast() in page scripts */
.toast.show {
  display: flex;
}

.toast strong {
  font-size: 13px;
}

.toast small {
  display: block;
  margin-top: 2px;
  color: rgba(255, 255, 255, 0.68);
}

/* Manual close button in the toast */
.toast .x {
  margin-left: auto;
  height: 30px;
  width: 30px;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-weight: 900;
}

.toast .x:hover {
  background: rgba(255, 255, 255, 0.08);
}

/* ==========================================================================
   AI Suggest Feature
   Warm amber/gold color scheme — intentionally inverted from the dark site
   theme so the AI affordance stands out as something special.

   Classes involved:
     .ai-suggest-btn                  — the "Suggest with AI" button in the form
     .ai-suggest-btn.is-ready        — pulsing amber glow when AI enabled + fields filled
     .ai-suggest-btn.is-loading      — dimmed + spin state during API call
     .ai-suggest-btn.ai-feature-disabled — grayed out when AI features are off in Settings
     .modal-panel             — sliding two-panel container inside .modal
     .modal-panel.show-ai     — slides left to reveal the AI panel
     .modal-form-panel        — left panel (the existing form)
     .modal-ai-panel          — right panel (AI suggestion view)
     .ai-panel-header         — sparkle icon + title row inside AI panel
     .ai-suggestion-box       — scrollable box that holds the suggestion text
     .ai-panel-actions        — overrides modal-actions justify for AI panel
     .modal.ai-loading        — shimmer sweep on modal border while loading
   ========================================================================== */

/* --------------------------------------------------------------------------
   AI Suggest button
   Full-width amber button below the notes field — same visual language as
   the AI Quick Add button in the applications header.
   -------------------------------------------------------------------------- */
.ai-suggest-btn {
  width: 100%;
  margin-top: 12px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 12px;
  border: 1px solid rgba(251, 191, 36, 0.32);
  background: linear-gradient(135deg, rgba(251, 191, 36, 0.12), rgba(245, 158, 11, 0.07));
  color: rgb(251, 191, 36);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: background 0.22s ease, border-color 0.22s ease,
              box-shadow 0.22s ease, transform 0.15s ease, opacity 0.2s ease;
}

/* Shimmer sweep on hover */
.ai-suggest-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(251, 191, 36, 0.14) 45%,
    rgba(251, 191, 36, 0.22) 50%,
    rgba(251, 191, 36, 0.14) 55%,
    transparent 100%
  );
  background-size: 250% 100%;
  background-position: -100% 0;
  transition: background-position 0.55s ease;
  pointer-events: none;
}

.ai-suggest-btn:hover::before {
  background-position: 150% 0;
}

.ai-suggest-btn:hover {
  background: linear-gradient(135deg, rgba(251, 191, 36, 0.2), rgba(245, 158, 11, 0.13));
  border-color: rgba(251, 191, 36, 0.55);
  box-shadow: 0 0 22px rgba(251, 191, 36, 0.18), 0 2px 8px rgba(0, 0, 0, 0.2);
  transform: translateY(-1px);
}

.ai-suggest-btn:active {
  transform: translateY(0);
  box-shadow: none;
}

/* .is-ready: pulsing glow signals AI can act on the filled fields */
.ai-suggest-btn.is-ready {
  animation: ai-pulse 2.4s ease-in-out infinite;
}

@keyframes ai-pulse {
  0%, 100% { box-shadow: 0 0 0 0   rgba(251, 191, 36, 0.45); }
  50%       { box-shadow: 0 0 0 9px rgba(251, 191, 36, 0); }
}

/* .is-loading: dim + spin icon while the API call is in flight */
.ai-suggest-btn.is-loading {
  opacity: 0.6;
  cursor: not-allowed;
  animation: none;
  transform: none;
}

.ai-suggest-btn.is-loading #aiSuggestIcon {
  animation: ai-spin 0.75s linear infinite;
}

/* .ai-feature-disabled: AI is off in Settings — button visible but inactive.
   DEPENDENCY: applications.js toggles this class via localStorage jat_ai_enabled. */
.ai-suggest-btn.ai-feature-disabled {
  opacity: 0.35;
  cursor: not-allowed;
  animation: none;
  transform: none;
}

.ai-suggest-btn.ai-feature-disabled:hover {
  background: linear-gradient(135deg, rgba(251, 191, 36, 0.12), rgba(245, 158, 11, 0.07));
  border-color: rgba(251, 191, 36, 0.32);
  box-shadow: none;
}

.ai-suggest-btn.ai-feature-disabled::before {
  display: none;
}

@keyframes ai-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* --------------------------------------------------------------------------
   Two-panel sliding container
   Both panels are min-width:100% so only one fits in the visible window.
   .show-ai translates left by 100% to reveal the AI panel.
   -------------------------------------------------------------------------- */
.modal-panel {
  display: flex;
  /* No overflow:hidden here — .modal already clips the second panel.
     Adding it here collapses the container height and blanks the modal. */
}

.modal-form-panel,
.modal-ai-panel {
  min-width: 100%;
  display: flex;
  flex-direction: column;
}

/* Slide transition — smooth cubic-bezier for a polished feel */
.modal-panel {
  transition: transform 0.38s cubic-bezier(0.4, 0, 0.2, 1);
}

.modal-panel.show-ai {
  transform: translateX(-100%);
}

/* --------------------------------------------------------------------------
   AI panel content
   -------------------------------------------------------------------------- */

/* Header row: sparkle icon + "AI Suggested Notes" title */
.ai-panel-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  color: rgba(255, 220, 100, 0.9);
}

.ai-panel-header h4 {
  font-size: 14px;
  font-weight: 800;
  color: rgba(255, 220, 100, 0.9);
  margin: 0;
  letter-spacing: 0.2px;
}

/* Scrollable box that holds the generated suggestion text */
.ai-suggestion-box {
  flex: 1;
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  padding: 14px;
  min-height: 180px;
  max-height: 340px;
  overflow-y: auto;
  font-size: 13.5px;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.88);
  white-space: pre-wrap;
  word-break: break-word;
}

/* Loading state inside the suggestion box — centered pulsing dot */
.ai-suggestion-box.is-loading {
  display: flex;
  align-items: center;
  justify-content: center;
}

.ai-loading-dots {
  display: flex;
  gap: 8px;
  align-items: center;
}

.ai-loading-dots span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(255, 220, 100, 0.7);
  animation: ai-dot-bounce 1.4s ease-in-out infinite;
}

.ai-loading-dots span:nth-child(2) { animation-delay: 0.2s; }
.ai-loading-dots span:nth-child(3) { animation-delay: 0.4s; }

@keyframes ai-dot-bounce {
  0%, 80%, 100% { transform: scale(0.7); opacity: 0.5; }
  40%           { transform: scale(1);   opacity: 1;   }
}

/* AI panel actions row: Discard left, Accept right */
.ai-panel-actions {
  justify-content: space-between;
}

/* --------------------------------------------------------------------------
   Modal glow while loading (.modal.ai-loading)
   Pulsing amber box-shadow around the modal border — clean and premium.
   No pseudo-element overlay so modal content is never obscured.
   -------------------------------------------------------------------------- */
.modal.ai-loading {
  animation: modal-ai-glow 2s ease-in-out infinite;
}

@keyframes modal-ai-glow {
  0%, 100% {
    box-shadow: var(--shadow),
      0 0 0 1px rgba(255, 200, 60, 0.2),
      0 0 18px rgba(255, 190, 50, 0.07);
  }
  50% {
    box-shadow: var(--shadow),
      0 0 0 2px rgba(255, 220, 100, 0.52),
      0 0 36px rgba(255, 200, 60, 0.2),
      0 0 72px rgba(255, 190, 50, 0.09);
  }
}

/* ==========================================================================
   Mobile — Modal as bottom sheet (≤480px)
   On small screens the centered modal becomes a bottom sheet that slides up
   from the bottom edge, with only the top corners rounded.
   ========================================================================== */

@media (max-width: 480px) {
  /* Backdrop anchors to bottom */
  .modal-backdrop {
    padding: 0;
    align-items: flex-end;
  }

  .modal-backdrop.show {
    align-items: flex-end;
  }

  /* Full-width sheet with rounded top corners only.
     max-height uses svh (small viewport height) so the sheet doesn't
     cover the browser address bar on iOS; falls back to vh. */
  .modal {
    width: 100%;
    border-radius: 22px 22px 0 0;
    max-height: 90svh;
    max-height: 90vh; /* fallback for browsers without svh */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  /* Modal body scrolls independently so header + actions always stay visible */
  .modal-body {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    flex: 1;
  }

  /* Pull handle accent at top of sheet — visual affordance for drag-to-dismiss */
  .modal-top::before {
    content: "";
    display: block;
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    width: 36px;
    height: 4px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.22);
  }

  .modal-top {
    position: relative;
    padding-top: 20px;
  }
}
