/* --- Affiliate banners (public rotator) --- */
.fl-affiliate {
  background: var(--bg, #f4f5f7);
  padding: 2.2rem 3vw 2.4rem;
  border-top: 1px solid var(--line, #e2e5ea);
}
.fl-affiliate-inner {
  /* Own pages set --page-width; embedded on a host page it keeps the old width. */
  max-width: var(--page-width, 970px);
  margin: 0 auto;
  text-align: center;
}
.fl-affiliate-label {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: ui-monospace, 'IBM Plex Mono', monospace;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted, #5c6370);
  margin: 0 0 0.7rem;
}
.fl-affiliate-info {
  position: relative;
  display: inline-block;
}
.fl-affiliate-info summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 50%;
  border: 1px solid currentColor;
  font-family: Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-size: 0.7rem;
  letter-spacing: normal;
  text-transform: none;
  line-height: 1;
  color: inherit;
  opacity: 0.75;
  cursor: pointer;
  list-style: none;
}
.fl-affiliate-info summary::-webkit-details-marker,
.fl-affiliate-info summary::marker {
  display: none;
  content: '';
}
.fl-affiliate-info summary:hover,
.fl-affiliate-info summary:focus-visible,
.fl-affiliate-info[open] summary {
  opacity: 1;
}
/* The popup keeps one fixed dark design everywhere: the owner's label and
   background colors, the rotator theme link color, and the host page's own
   link styling must never reach it, so the class is doubled to outrank
   selectors like `body.is-rotator a`. */
.fl-affiliate-info-pop.fl-affiliate-info-pop {
  position: absolute;
  z-index: 20;
  top: calc(100% + 0.5rem);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: min(260px, 80vw);
  padding: 0.65rem 0.75rem;
  border-radius: 8px;
  background: #1c1f24;
  color: #f4f5f7;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  font-size: 0.75rem;
  font-style: normal;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: normal;
  text-align: left;
  text-transform: none;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
}
.fl-affiliate-info-pop.fl-affiliate-info-pop a {
  color: #8fb4ff;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.12em;
}
.fl-affiliate-info-pop.fl-affiliate-info-pop a:hover,
.fl-affiliate-info-pop.fl-affiliate-info-pop a:focus-visible {
  color: #b7cdff;
}
.fl-affiliate-frame {
  min-height: 90px;
}
.fl-affiliate-slide {
  display: inline-block;
  max-width: 100%;
}
.fl-affiliate-slide[hidden] {
  display: none !important;
}
.fl-affiliate-slide img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
}
.fl-affiliate-host {
  border: 0;
  margin: 0;
  padding: 0.6rem;
  max-width: 100%;
  box-sizing: border-box;
}
.fl-affiliate-host .fl-affiliate-inner {
  max-width: none;
}
.rotator-closed {
  box-sizing: border-box;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.4;
  color: var(--rotator-ink, #1c1f24);
  -webkit-font-smoothing: antialiased;
}
.rotator-closed .fl-affiliate-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  max-width: 36em;
  width: 100%;
  box-sizing: border-box;
  padding: 0.15em 0.35em;
}
.rotator-closed .fl-affiliate-label {
  margin: 0;
  font-size: 0.7em;
}
.rotator-closed .rotator-closed-msg,
.fl-affiliate .rotator-closed-msg {
  margin: 0;
  font-size: 1.1em;
  font-weight: 600;
  color: var(--rotator-ink, #1c1f24);
  overflow-wrap: break-word;
  text-wrap: balance;
}
.rotator-closed .rotator-closed-from,
.fl-affiliate .rotator-closed-from {
  margin: 0;
  font-size: 0.9em;
  color: var(--rotator-muted, #5c6370);
  overflow-wrap: break-word;
}
.rotator-closed .rotator-closed-from a {
  color: var(--rotator-link, #24468f);
  font-weight: 650;
  text-decoration: underline;
  text-underline-offset: 0.12em;
}
.rotator-closed .rotator-closed-from a:hover {
  color: var(--rotator-link-hover, #1a3570);
}
.fl-affiliate-host.rotator-closed {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 5.5em;
  padding: 0.85em 0.75em;
}
/* The pager sits on other people's pages, where `button { ... !important }`
   in the host stylesheet would otherwise recolor and resize the dots — that is
   what made them come out in three different colors. Class names are doubled
   and every visual property is marked important, so the row always renders the
   same: one ink for all dots, the current one dimmed up and stretched to a
   pill. The padding is only the tap target; the background is clipped to the
   content box, so the visible dot stays small. */
.fl-affiliate-dots.fl-affiliate-dots {
  display: flex !important;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.1rem;
  margin: 0.7rem 0 0;
  padding: 0;
  line-height: 0;
}
.fl-affiliate:not(.is-enhanced) .fl-affiliate-dots.fl-affiliate-dots { display: none !important; }
.fl-affiliate-dot.fl-affiliate-dot {
  appearance: none !important;
  -webkit-appearance: none !important;
  box-sizing: content-box !important;
  flex: 0 0 auto;
  width: 8px !important;
  height: 8px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  max-width: none !important;
  padding: 6px !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 999px !important;
  background-color: var(--rotator-dot, #8b9099) !important;
  background-image: none !important;
  background-clip: content-box !important;
  box-shadow: none !important;
  opacity: var(--rotator-dot-idle, 0.34) !important;
  color: inherit;
  font: inherit;
  text-indent: 0;
  outline: 0;
  cursor: pointer;
  transition: opacity 0.18s ease, width 0.18s ease;
  -webkit-tap-highlight-color: transparent;
}
.fl-affiliate-dot.fl-affiliate-dot:hover,
.fl-affiliate-dot.fl-affiliate-dot:focus,
.fl-affiliate-dot.fl-affiliate-dot:active {
  background-color: var(--rotator-dot, #8b9099) !important;
  opacity: 0.65 !important;
}
.fl-affiliate-dot.fl-affiliate-dot[aria-current="true"],
.fl-affiliate-dot.fl-affiliate-dot[aria-current="true"]:hover,
.fl-affiliate-dot.fl-affiliate-dot[aria-current="true"]:focus,
.fl-affiliate-dot.fl-affiliate-dot[aria-current="true"]:active {
  width: 20px !important;
  background-color: var(--rotator-dot, #8b9099) !important;
  opacity: 1 !important;
}
.fl-affiliate-dot.fl-affiliate-dot:focus-visible {
  outline: 2px solid var(--rotator-dot, #8b9099);
  outline-offset: -3px;
}
@media (prefers-reduced-motion: reduce) {
  .fl-affiliate-dot.fl-affiliate-dot { transition: none; }
}
@media (max-width: 720px) and (orientation: portrait) {
  .fl-affiliate-frame {
    min-height: 0;
    line-height: 0;
  }
  .fl-affiliate-slide {
    vertical-align: top;
  }
  .fl-affiliate-dots.fl-affiliate-dots {
    margin-top: 0.8rem;
    gap: 0;
  }
  /* Roomier tap targets on a phone; the visible dot keeps its size. */
  .fl-affiliate-dot.fl-affiliate-dot {
    padding: 8px !important;
  }
}

.admin-affiliate-preview img {
  display: block;
  max-width: 100%;
  max-height: 120px;
  height: auto;
  margin: 0.35rem 0 1rem;
  border: 0;
  border-radius: 6px;
  background: var(--paper-2, #f8f9fb);
}

.affiliate-source {
  border: 2px solid var(--field-line, var(--line));
  border-radius: var(--radius);
  padding: 0.7rem 0.9rem 0.9rem;
  margin: 0.4rem 0 0.8rem;
  background: var(--field, var(--paper-2));
}
.affiliate-source legend,
.affiliate-pos legend {
  font-family: var(--font-display);
  font-size: 0.88rem;
  font-weight: 500;
  padding: 0 0.3rem;
  color: var(--ink);
}
.affiliate-source label.radio {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 400;
  margin: 0.35rem 0;
}
.affiliate-source label.radio input[type="radio"] {
  width: auto;
  margin: 0;
}
/* Text-banner fonts. GD draws the saved banner from the same TTF files, so the
   preview must use these faces and no fallback – see fonts/banner/README.md.
   Nothing on the page is set in them, so they load only when the preview asks
   for them through document.fonts.load(). */
@font-face {
  font-family: "Banner Grotesk";
  src: url("fonts/banner/SpaceGrotesk-Bold.ttf") format("truetype");
  font-display: block;
}
@font-face {
  font-family: "Banner Montserrat";
  src: url("fonts/banner/Montserrat-Bold.ttf") format("truetype");
  font-display: block;
}
@font-face {
  font-family: "Banner Playfair";
  src: url("fonts/banner/PlayfairDisplay-Bold.ttf") format("truetype");
  font-display: block;
}
@font-face {
  font-family: "Banner Bebas";
  src: url("fonts/banner/BebasNeue-Regular.ttf") format("truetype");
  font-display: block;
}
@font-face {
  font-family: "Banner Pacifico";
  src: url("fonts/banner/Pacifico-Regular.ttf") format("truetype");
  font-display: block;
}
@font-face {
  font-family: "Banner Mono";
  src: url("fonts/banner/SpaceMono-Bold.ttf") format("truetype");
  font-display: block;
}
.affiliate-compose-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 0 1.2rem;
}
.affiliate-compose-grid .span-all { grid-column: 1 / -1; }
.affiliate-compose-grid .span2 { grid-column: span 2; }
/* Only some fields carry a hint line ("Text" has one, "Font" does not), so the
   labels stretch over the row and the control drops to the bottom of it – the
   inputs on a row then line up instead of stepping. */
.affiliate-compose-grid > label:not(.checkbox):not(.radio) > input,
.affiliate-compose-grid > label:not(.checkbox):not(.radio) > select,
.affiliate-compose-grid .affiliate-mode-block > label:not(.checkbox):not(.radio) > input,
.affiliate-compose-grid .affiliate-mode-block > label:not(.checkbox):not(.radio) > select {
  margin-top: auto;
}
/* Logo-only and text-only fields sit in the same grid as the shared background
   fields, so the wrapper must not become a grid item of its own. */
.affiliate-compose-grid .affiliate-mode-block { display: contents; }
.affiliate-mode-block[hidden] { display: none; }
.affiliate-compose-grid input[type="color"] {
  height: 2.8rem;
  padding: 0.2rem;
  cursor: pointer;
  border-radius: 8px;
  border: 2px solid var(--field-line, var(--line));
  background: var(--field, var(--paper-2));
}
.affiliate-compose-grid input[type="range"] {
  width: 100%;
  accent-color: var(--blue);
}
.affiliate-pos {
  border: 2px solid var(--field-line, var(--line));
  border-radius: var(--radius);
  padding: 0.7rem 0.9rem 0.9rem;
  margin: 0.4rem 0 0.8rem;
  background: var(--field, var(--paper-2));
}
.affiliate-pos-grid {
  display: grid;
  grid-template-columns: repeat(3, 2.2rem);
  gap: 0.35rem;
}
.affiliate-pos-cell {
  width: 2.2rem;
  height: 2.2rem;
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--raised, #fff);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
}
.affiliate-pos-cell input {
  appearance: none;
  width: 0.7rem;
  height: 0.7rem;
  margin: 0;
  border-radius: 50%;
  background: var(--line-strong, #c5cad3);
}
.affiliate-pos-cell:has(input:checked) {
  border-color: var(--blue);
  background: oklch(55% 0.16 140 / 0.18);
}
.affiliate-pos-cell input:checked {
  background: var(--blue);
}
.logo-picker { margin: 0.4rem 0 0.9rem; }
.logo-picker .admin-tip-preview-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}
.logo-picker-manage {
  text-transform: none;
  letter-spacing: normal;
  font-weight: 600;
  font-size: 0.8rem;
}
.logo-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(4.4rem, 1fr));
  gap: 0.5rem;
  margin-top: 0.4rem;
}
.logo-picker-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
  padding: 0.4rem 0.3rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper-2);
  cursor: pointer;
  text-align: center;
}
.logo-picker-cell:has(input:checked) {
  border-color: var(--blue);
  background: oklch(55% 0.16 140 / 0.18);
}
.logo-picker-cell input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
}
.logo-picker-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 4px;
  background: repeating-conic-gradient(oklch(28% 0.015 260) 0% 25%, oklch(22% 0.013 260) 0% 50%) 50% / 0.7rem 0.7rem;
  overflow: hidden;
}
.logo-picker-thumb img {
  max-width: 100%;
  max-height: 100%;
}
.logo-picker-thumb-upload {
  background: var(--paper-2);
  border: 1px dashed var(--line);
  color: var(--muted);
  font-size: 1.3rem;
  font-weight: 300;
}
.logo-picker-name {
  font-size: 0.72rem;
  font-weight: 400;
  color: var(--muted);
  max-width: 4.4rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.logo-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 1rem;
}
.logo-gallery-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.8rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper-2);
  text-align: center;
}
.logo-gallery-item:hover,
.logo-gallery-item:focus-within {
  z-index: 2;
}
.logo-gallery-thumb {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  font: inherit;
  color: inherit;
  line-height: 0;
  cursor: zoom-in;
  appearance: none;
  -webkit-appearance: none;
}
.logo-gallery-thumb:focus-visible {
  outline: none;
  box-shadow: var(--focus);
}
.logo-gallery-thumb img {
  display: block;
  width: 100%;
  height: 5.5rem;
  object-fit: contain;
  border-radius: 4px;
  background: repeating-conic-gradient(oklch(28% 0.015 260) 0% 25%, oklch(22% 0.013 260) 0% 50%) 50% / 0.9rem 0.9rem;
  pointer-events: none;
}
.logo-gallery-name {
  font-size: 0.85rem;
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.logo-gallery-usage {
  position: relative;
  font-size: 0.78rem;
  cursor: help;
}
.logo-gallery-usage-pop {
  position: absolute;
  z-index: 5;
  left: 50%;
  bottom: calc(100% + 0.45rem);
  transform: translateX(-50%);
  width: max-content;
  max-width: min(14rem, 70vw);
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--ink);
  font-size: 0.78rem;
  font-style: normal;
  font-weight: 400;
  line-height: 1.4;
  text-align: left;
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.logo-gallery-usage:hover .logo-gallery-usage-pop,
.logo-gallery-usage:focus .logo-gallery-usage-pop,
.logo-gallery-usage:focus-within .logo-gallery-usage-pop {
  opacity: 1;
  visibility: visible;
}
.logo-gallery-usage-pop-label {
  display: block;
  margin-bottom: 0.2rem;
  color: var(--muted);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.logo-gallery-usage-pop ul {
  margin: 0;
  padding-left: 1.05rem;
}
.logo-gallery-usage-pop li {
  margin: 0.08rem 0;
}
.app-dialog.logo-gallery-preview {
  width: min(46rem, calc(100vw - 2rem));
}
.logo-gallery-preview-img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(70vh, 36rem);
  margin: 0 auto;
  object-fit: contain;
  border-radius: 4px;
  background: repeating-conic-gradient(oklch(28% 0.015 260) 0% 25%, oklch(22% 0.013 260) 0% 50%) 50% / 0.9rem 0.9rem;
}
.logo-gallery-size {
  font-size: 0.78rem;
}
.logo-gallery-item form {
  margin: 0;
}
/* Rename box: the gallery lives outside .grid-form, so its input carries the
   form styling itself. The <details> keeps the card compact — the name with a
   pencil beside it is all that shows until the pencil is clicked. */
.logo-gallery-rename {
  width: 100%;
}
.logo-gallery-rename > summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
  border-radius: var(--radius-sm);
  padding: 0.1rem 0.2rem;
}
.logo-gallery-rename > summary::-webkit-details-marker { display: none; }
.logo-gallery-rename > summary::marker { content: none; }
.logo-gallery-pencil {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--muted);
  transition: color 0.15s ease;
}
.logo-gallery-pencil svg {
  width: 0.9rem;
  height: 0.9rem;
}
.logo-gallery-rename > summary:hover .logo-gallery-pencil,
.logo-gallery-rename[open] > summary .logo-gallery-pencil {
  color: var(--blue);
}
.logo-gallery-rename > summary:focus-visible {
  outline: none;
  box-shadow: var(--focus);
}
.logo-gallery-item .logo-gallery-rename-form {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem;
  width: 100%;
  margin-top: 0.4rem;
}
.logo-gallery-rename-form input[type="text"] {
  flex: 1 1 100%;
  min-width: 0;
  font-family: inherit;
  font-size: 0.82rem;
  padding: 0.4rem 0.55rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--sunken);
  box-shadow: inset 0 2px 4px oklch(5% 0.01 260 / 0.6), inset 0 1px 0 oklch(100% 0 0 / 0.03);
  color: var(--ink);
  text-align: center;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.logo-gallery-rename-form input[type="text"]::placeholder {
  color: oklch(50% 0.02 260);
}
.logo-gallery-rename-form input[type="text"]:focus-visible {
  outline: none;
  border-color: var(--blue);
  box-shadow: var(--focus);
}
.logo-gallery-rename-form button {
  font-size: 0.82rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  min-height: 2.2rem;
}

.affiliate-compose-preview-wrap {
  margin: 0.4rem 0 0.8rem;
  background: var(--paper-2);
  padding: 0.7rem;
  border-radius: var(--radius);
}
/* The stage carries the rotator's own background color (set from
   data-preview-bg by affiliate-compose.js, since CSP blocks style attributes)
   so rounded corners and fades are judged against the real page. */
.affiliate-compose-preview-stage {
  display: flex;
  justify-content: center;
  padding: 0.7rem;
  border-radius: var(--radius-sm);
  background: var(--preview-bg, var(--paper-2));
}
.affiliate-compose-preview {
  display: block;
  max-width: 100%;
  height: auto;
  border: 0;
  border-radius: 0;
  background: transparent;
}
@media (max-width: 720px) {
  .affiliate-compose-grid { grid-template-columns: 1fr 1fr; }
}

.grid-form:has([name="banner_source"][value="url"]:checked) .affiliate-panel:not([data-source~="url"]),
.grid-form:has([name="banner_source"][value="upload"]:checked) .affiliate-panel:not([data-source~="upload"]),
.grid-form:has([name="banner_source"][value="compose"]:checked) .affiliate-panel:not([data-source~="compose"]),
.grid-form:has([name="banner_source"][value="text"]:checked) .affiliate-panel:not([data-source~="text"]) {
  display: none;
}
/* The compose panel serves both drawn kinds: hide the fields of the other one. */
.grid-form:has([name="banner_source"][value="compose"]:checked) .affiliate-mode-block[data-mode="text"],
.grid-form:has([name="banner_source"][value="text"]:checked) .affiliate-mode-block[data-mode="compose"] {
  display: none;
}
