
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .tooltip.tooltip-black {
    --tooltip-color: #000000;
    --tooltip-text-color: #ffffff;
  }

  /* Chatbot assistant answers — restore list styling stripped by preflight */
  .chatbot-answer ul {
    list-style: disc;
    padding-left: 1.25rem;
    margin: 0.375rem 0;
  }

  .chatbot-answer ol {
    list-style: decimal;
    padding-left: 1.25rem;
    margin: 0.375rem 0;
  }

  .chatbot-answer li + li {
    margin-top: 0.25rem;
  }

  .chatbot-answer p + p,
  .chatbot-answer p + ul,
  .chatbot-answer p + ol,
  .chatbot-answer ul + p,
  .chatbot-answer ol + p {
    margin-top: 0.5rem;
  }

  .chatbot-wiggle {
    animation: chatbot-wiggle 0.9s ease-in-out 2;
  }

  /* ---- Competition guides ---- */

  /* Long-form guide article typography. Defined here rather than as inline
     utilities because the body is ~2,000 words of prose; @tailwindcss/typography's
     `prose` defaults diverge from the design enough that overriding them costs
     more than translating the rules directly. */
  .guide-body section {
    @apply pb-16;
  }

  /* For a section that opens with a table rather than a heading, so it needs
     less room beneath it than a full prose section */
  .guide-body section.guide-section-tight {
    @apply pb-12;
  }

  .guide-body section[id],
  .guide-body h3 {
    scroll-margin-top: 6rem;
  }

  .guide-body h2 {
    @apply mb-5 text-2xl md:text-3xl font-black leading-snug tracking-tight text-base-content text-pretty;
  }

  .guide-body h2 .teal {
    @apply text-primary;
  }

  .guide-body h3 {
    @apply mt-10 mb-4 text-lg font-bold tracking-tight text-base-content text-pretty;
  }

  .guide-body h3:first-child {
    @apply mt-0;
  }

  .guide-body p {
    @apply mb-5 text-base leading-relaxed text-base-content/70 text-pretty;
  }

  .guide-body p strong,
  .guide-body li strong {
    @apply text-base-content font-semibold;
  }

  .guide-body ul,
  .guide-body ol {
    @apply mb-6 pl-5 flex flex-col gap-3;
  }

  .guide-body ul {
    list-style: disc;
  }

  .guide-body ol {
    list-style: decimal;
  }

  .guide-body li {
    @apply text-base leading-relaxed text-base-content/70;
  }

  .guide-body li::marker {
    @apply text-primary;
  }

  .guide-body blockquote {
    @apply mb-5 py-5 px-6 bg-primary/10 border-l-[3px] border-primary rounded-r-lg text-lg italic font-semibold leading-normal text-base-content;
  }

  /* Callout */
  .guide-callout {
    @apply flex gap-4 mb-6 py-5 px-6 bg-primary/10 border border-primary/20 border-l-[3px] border-l-primary rounded-r-xl;
  }

  .guide-callout > .guide-callout-icon {
    @apply flex-none mt-0.5 text-primary;
  }

  .guide-body .guide-callout p {
    @apply mb-4;
  }

  .guide-body .guide-callout p:last-child {
    @apply mb-0;
  }

  .guide-body .guide-callout p.lead {
    @apply text-lg font-bold text-base-content;
  }

  /* Tick / cross lists. The `.guide-body` prefix is needed on every rule here:
     `.guide-body ul` already sets a disc marker and left padding, and outranks a
     single class on its own. */
  .guide-body .guide-marklist {
    @apply mb-6 p-0 flex flex-col gap-3;
    list-style: none;
  }

  .guide-body .guide-marklist li {
    @apply flex gap-3 items-start text-base leading-relaxed text-base-content/70;
  }

  .guide-body .guide-marklist .guide-mark {
    @apply flex-none mt-1 text-primary;
  }

  .guide-body .guide-marklist-crosses .guide-mark {
    @apply text-base-content/50;
  }

  /* Numbered steps: a bold lead-in phrase on its own line, then the detail */
  .guide-body .guide-steps {
    @apply pl-6 gap-5;
  }

  .guide-body .guide-steps > li {
    @apply pl-2;
  }

  .guide-body .guide-steps > li::marker {
    @apply font-bold text-primary;
  }

  .guide-body .guide-step-name {
    @apply block mb-1 text-base font-bold text-base-content;
  }

  /* Tables */
  .guide-table-wrap {
    @apply mb-6 border border-base-300 rounded-xl overflow-x-auto shadow-sm;
  }

  .guide-table-wrap table {
    @apply w-full border-collapse min-w-[520px];
  }

  .guide-table-wrap thead th {
    @apply bg-primary/10 py-4 px-5 text-left text-sm font-bold text-base-content whitespace-nowrap;
  }

  .guide-table-wrap tbody td {
    @apply py-4 px-5 border-t border-base-300 text-sm leading-normal text-base-content/70 align-top;
  }

  .guide-table-wrap tbody td:first-child {
    @apply text-base-content font-medium;
  }

  .guide-table-wrap tbody tr:hover td {
    @apply bg-base-200;
  }

  /* Prose links. Scoped to p/li rather than `.guide-body a` so it cannot reach the
     closing CTA, which is a direct child of .guide-final-card styled as a button —
     `.guide-body a` outranks the button's own utilities and would underline it and
     override its text colour. */
  .guide-body p a,
  .guide-body li a {
    @apply text-primary font-medium underline underline-offset-2 decoration-primary/40 hover:decoration-primary;
  }

  /* Screenshot embeds */
  .guide-shot {
    @apply flex items-center justify-center p-3 md:p-5 bg-base-200 border border-base-300 rounded-xl shadow-md overflow-hidden;
  }

  .guide-shot img {
    @apply block w-full h-auto rounded-lg;
  }

  /* Infographic */
  .guide-body figure {
    @apply mb-6;
  }

  .guide-figure-scroll {
    @apply overflow-x-auto border border-base-300 rounded-xl shadow-sm bg-base-100;
  }

  .guide-figure-scroll svg {
    @apply block w-full min-w-[560px] h-auto;
  }

  .guide-body figcaption {
    @apply mt-3 text-xs text-base-content/50 text-pretty;
  }

  /* Closing CTA card */
  .guide-final-card {
    @apply bg-primary/10 border border-primary/20 border-l-[3px] border-l-primary rounded-r-2xl p-8;
  }

  /* ---- Blog post body ---- */

  /* Long-form typography for ActionText blog bodies, defined explicitly for the
     same reason .guide-body is: the @tailwindcss/typography `prose` defaults do
     not match this design, and relying on them left paragraphs with no visible
     separation. The tag set here is exactly the one blog_automation's prompt
     allows an article to use, so anything the agent can emit is styled. */
  .lexxy-content p {
    @apply mb-4 text-base leading-relaxed text-base-content text-pretty;
  }

  .lexxy-content h2 {
    @apply mt-9 mb-3 text-2xl md:text-3xl font-black leading-snug tracking-tight text-base-content text-pretty;
  }

  .lexxy-content h3 {
    @apply mt-7 mb-3 text-lg font-bold tracking-tight text-base-content text-pretty;
  }

  .lexxy-content h2:first-child,
  .lexxy-content h3:first-child {
    @apply mt-0;
  }

  .lexxy-content ul,
  .lexxy-content ol {
    @apply mb-4 pl-5 flex flex-col gap-2;
  }

  .lexxy-content ul {
    list-style: disc;
  }

  .lexxy-content ol {
    list-style: decimal;
  }

  .lexxy-content li {
    @apply text-base leading-relaxed text-base-content;
  }

  .lexxy-content li::marker {
    @apply text-primary;
  }

  .lexxy-content p strong,
  .lexxy-content li strong {
    @apply text-base-content font-semibold;
  }

  .lexxy-content blockquote {
    @apply mb-4 py-4 px-6 bg-primary/10 border-l-[3px] border-primary rounded-r-lg text-lg italic font-semibold leading-normal text-base-content;
  }

  .lexxy-content p a,
  .lexxy-content li a {
    @apply text-primary font-medium underline underline-offset-2 decoration-primary/40 hover:decoration-primary;
  }

  /* ---- Blog post tables ---- */

  /* Never set the table to max-content: that opts every cell out of wrapping, so
     the table grows to the width of its longest line and scrolls at every
     viewport. It fills the column instead, and min-width is the floor that stops
     columns compressing past readable, which is what the wrapper scrolls. */
  .blog-table-wrap {
    @apply mb-6 overflow-x-auto;
  }

  .lexxy-content table {
    @apply w-full min-w-[520px] border-collapse text-sm;
  }

  /* Keyed on th/td rather than thead/tbody: the agent authors a thead, Lexxy
     re-serialises the same header row into tbody, and both must render alike. */
  .lexxy-content th {
    @apply bg-primary/10 py-3 px-4 text-left font-bold text-base-content;
  }

  .lexxy-content td {
    @apply py-3 px-4 border-t border-base-300 text-base-content align-top;
  }

  .lexxy-content td:first-child {
    @apply text-base-content font-medium;
  }

  /* Lexxy wraps every cell's content in a paragraph. Left alone it takes the
     article paragraph's margin and type scale, which stretches every row, so it
     is pinned back to the table's own. */
  .lexxy-content th > p,
  .lexxy-content td > p {
    @apply mb-0 text-sm;
  }

  /* Target TRL slider (companies/_target_trl_slider). The native range keeps
     drag, touch and keyboard, but its thumb is invisible — a styled handle is
     drawn over it so movement can animate. Vendor pseudo-elements can't be
     reached with utilities. */
  .trl-slider-range {
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    cursor: pointer;
  }

  .trl-slider-range:focus {
    outline: none;
  }

  .trl-slider-range::-webkit-slider-runnable-track {
    height: 18px;
    background: transparent;
  }

  .trl-slider-range::-moz-range-track {
    height: 18px;
    background: transparent;
  }

  .trl-slider-range::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    opacity: 0;
    cursor: grab;
  }

  .trl-slider-range::-moz-range-thumb {
    width: 18px;
    height: 18px;
    border: 0;
    opacity: 0;
    cursor: grab;
  }

  /* Uses the standalone `scale` property so it composes with the handle's
     translate utilities instead of overwriting them. */
  .trl-slider-pop {
    animation: trl-slider-pop 0.3s ease-out;
  }
}

@keyframes chatbot-wiggle {
  0%, 100% { transform: rotate(0deg); }
  20% { transform: rotate(-12deg); }
  40% { transform: rotate(10deg); }
  60% { transform: rotate(-8deg); }
  80% { transform: rotate(6deg); }
}

@media (prefers-reduced-motion: reduce) {
  .chatbot-wiggle {
    animation: none;
  }
}

@keyframes trl-slider-pop {
  50% { scale: 1.2; }
}

@media (prefers-reduced-motion: reduce) {
  .trl-slider-pop {
    animation: none;
  }
}
.session-form {
  margin: auto;
}

.devise-link-container {
  margin: 12px 0;

  a {
    margin-right: 12px;
    text-decoration: none;
    color: #00f;
  }
}

.subtle-background {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='49.294117647058826' height='49.294117647058826' viewBox='0 0 49.294117647058826 49.294117647058826'%3E%3Cpath d='M 0 0.5 L 49.294117647058826 0.5 M 0.5 0 L 0.5 49.294117647058826' stroke='rgb(237%2C 245%2C 247)' stroke-dasharray='5%2C5' stroke-width='1' /%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 50px 50px; /* Adjust based on your desired pattern size */
  background-position: center;
  min-height: 100vh; /* Ensure it covers the entire height of the page */
}
/*
 * Discover banner: entrance, and the hand-over from the daily greeting to the main
 * message. Plain CSS rather than Tailwind classes because the phases are set by the
 * discover-greeting Stimulus controller's phase value.
 */

@keyframes gh-icon-pop {
  0% { opacity: 0; transform: scale(0.5); }
  65% { opacity: 1; transform: scale(1.12); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes gh-message-slide-in {
  0% { opacity: 0; transform: translateX(-18px) translateY(6px); }
  100% { opacity: 1; transform: translateX(0) translateY(0); }
}

@keyframes gh-typing-dot {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.35; }
  30% { transform: translateY(-4px); opacity: 1; }
}

/* With no summary the banner closes after its greeting: the row collapses to nothing,
   then is hidden so the avatar's alt text and anything inside leave assistive tech too.
   Overflow is clipped only once closing, so the avatar's pop, ring and shadow aren't
   cut off while the banner is open. */
.gh-banner {
  display: grid;
  grid-template-rows: 1fr;
  transition:
    grid-template-rows 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.35s,
    opacity 0.4s ease 0.35s,
    visibility 0s linear 1s;
}

.gh-banner-inner {
  min-height: 0;
  padding-bottom: 1rem;
  transition: padding-bottom 0.6s cubic-bezier(0.22, 1, 0.36, 1) 0.35s;
}

[data-discover-greeting-phase-value="gone"].gh-banner {
  grid-template-rows: 0fr;
  opacity: 0;
  visibility: hidden;
}

[data-discover-greeting-phase-value="gone"] .gh-banner-inner {
  overflow: hidden;
  padding-bottom: 0;
}

.gh-avatar {
  position: relative;
  opacity: 0;
  animation: gh-icon-pop 0.65s cubic-bezier(0.22, 1, 0.36, 1) 0.1s both;
}

.gh-bubble {
  opacity: 0;
  animation: gh-message-slide-in 1.1s cubic-bezier(0.22, 1, 0.36, 1) 0.65s both;
}

@keyframes gh-avatar-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}

@keyframes gh-avatar-wave {
  0% { transform: rotate(0) scale(1); }
  15% { transform: rotate(-14deg) scale(1.1); }
  30% { transform: rotate(12deg) scale(1.1); }
  45% { transform: rotate(-10deg) scale(1.08); }
  60% { transform: rotate(8deg) scale(1.05); }
  80% { transform: rotate(-3deg) scale(1.02); }
  100% { transform: rotate(0) scale(1); }
}

@keyframes gh-avatar-ring {
  0% { opacity: 0.7; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.6); }
}

/* The avatar reacts to what it is saying: it bobs along with the typing dots, waves
   as the greeting lands, and sends out one soft ring. The icon itself is the target,
   not .gh-avatar, so these don't fight its entrance animation. */
[data-discover-greeting-phase-value="typing"] .gh-avatar-face {
  animation: gh-avatar-bob 1.2s ease-in-out infinite;
}

[data-discover-greeting-phase-value="greeting"] .gh-avatar-face {
  animation: gh-avatar-wave 1s ease-in-out 0.3s both;
}

[data-discover-greeting-phase-value="greeting"] .gh-avatar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid currentColor;
  pointer-events: none;
  animation: gh-avatar-ring 1.4s ease-out 0.3s both;
}

/* The messages share one grid cell, so the bubble keeps the tallest one's height and
   nothing below it jumps when they swap. */
.gh-layer {
  grid-area: 1 / 1;
  align-self: center;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition:
    opacity 0.45s ease,
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    visibility 0s linear 0.45s;
}

/* Leaving: lift away. Listed before the visible rules so those win on equal specificity. */
[data-discover-greeting-phase-value="greeting"] .gh-typing,
[data-discover-greeting-phase-value="main"] .gh-typing,
[data-discover-greeting-phase-value="gone"] .gh-typing,
[data-discover-greeting-phase-value="main"] .gh-greeting,
[data-discover-greeting-phase-value="gone"] .gh-greeting {
  transform: translateY(-10px);
}

/* Arriving: wait for the outgoing message to clear, then rise into place. */
[data-discover-greeting-phase-value="typing"] .gh-typing,
[data-discover-greeting-phase-value="greeting"] .gh-greeting,
[data-discover-greeting-phase-value="main"] .gh-main {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition:
    opacity 0.5s ease 0.25s,
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1) 0.25s,
    visibility 0s linear 0s;
}

/* The typing dots appear with the bubble, so there is nothing to wait for. */
[data-discover-greeting-phase-value="typing"] .gh-typing {
  transition-delay: 0s;
}

.gh-typing-dot {
  display: inline-block;
  height: 0.375rem;
  width: 0.375rem;
  border-radius: 9999px;
  background-color: currentColor;
  animation: gh-typing-dot 1.2s ease-in-out infinite;
}

.gh-typing-dot:nth-child(2) { animation-delay: 0.15s; }
.gh-typing-dot:nth-child(3) { animation-delay: 0.3s; }

@media (prefers-reduced-motion: reduce) {
  .gh-avatar,
  .gh-bubble {
    animation: none;
    opacity: 1;
  }

  .gh-banner,
  .gh-banner-inner,
  .gh-layer,
  [data-discover-greeting-phase-value] .gh-layer {
    transform: none;
    transition: none;
  }

  .gh-typing-dot,
  .gh-avatar-face,
  .gh-avatar::after {
    animation: none !important;
  }
}
/* Multi-Select Styles */
.multi-select {
  position: relative;
  width: 100%;
}

.multi-select-header {
  min-height: 42px;
  padding: 8px 12px;
  border: 1px solid #d1d5db;
  border-radius: 0.5rem;
  background-color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.2s;
}

.multi-select-header:hover {
  border-color: #9ca3af;
}

.multi-select-header-active {
  border-color: #3b82f6 !important;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.multi-select-header::after {
  content: '';
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid #6b7280;
  transition: transform 0.2s;
}

.multi-select-header-active::after {
  transform: translateY(-50%) rotate(180deg);
}

.multi-select-header-placeholder {
  color: #9ca3af;
  flex: 1;
}

.multi-select-header-placeholder.hidden {
  display: none;
}

.multi-select-selected-count {
  font-weight: 500;
  color: #1f2937;
}

.multi-select-selected-count.hidden {
  display: none;
}

.multi-select-options {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 4px;
  max-height: 300px;
  overflow-y: auto;
  background-color: white;
  border: 1px solid #d1d5db;
  border-radius: 0.5rem;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  z-index: 50;
  display: none;
}

.multi-select-header-active + .multi-select-options {
  display: block;
}

.multi-select-search {
  width: 100%;
  padding: 8px 12px;
  border: none;
  border-bottom: 1px solid #e5e7eb;
  outline: none;
  font-size: 14px;
}

.multi-select-search:focus {
  background-color: #f9fafb;
}

.multi-select-all {
  display: flex;
  align-items: center;
  padding: 10px 12px;
  cursor: pointer;
  border-bottom: 1px solid #e5e7eb;
  background-color: #f9fafb;
  font-weight: 500;
  transition: background-color 0.2s;
}

.multi-select-all:hover {
  background-color: #f3f4f6;
}

.multi-select-option {
  display: flex;
  align-items: center;
  padding: 10px 12px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.multi-select-option:hover {
  background-color: #f3f4f6;
}

.multi-select-option-radio {
  width: 18px;
  height: 18px;
  border: 2px solid #d1d5db;
  border-radius: 4px;
  margin-right: 10px;
  position: relative;
  transition: all 0.2s;
}

.multi-select-selected .multi-select-option-radio,
.multi-select-all.multi-select-selected .multi-select-option-radio {
  background-color: #3b82f6;
  border-color: #3b82f6;
}

.multi-select-selected .multi-select-option-radio::after,
.multi-select-all.multi-select-selected .multi-select-option-radio::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 2px;
  width: 4px;
  height: 8px;
  border: solid white;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.multi-select-option-text {
  flex: 1;
  font-size: 14px;
  color: #374151;
}
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *


 */
