:root {
  --bg: #f6f7f9;
  --card: #ffffff;
  --ink: #1c2330;
  --muted: #5b6472;
  --line: #dde2e9;
  --accent: #2456d6;
  --accent-ink: #ffffff;
  --ok: #1a7f4b;
  --err: #c0392b;
  --placeholder: #a9b1bd;
}
* { box-sizing: border-box; }
/* Several elements below set an explicit display (flex/grid), which would
   otherwise beat the browser default for [hidden] and keep them on screen. */
[hidden] { display: none !important; }
body {
  margin: 0;
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  background: var(--bg);
  color: var(--ink);
  line-height: 1.5;
}
.wrap { max-width: 980px; margin: 0 auto; padding: 2rem 1.25rem 4rem; }
header.site { margin-bottom: 1.5rem; }
header.site h1 { margin: 0; font-size: 1.6rem; flex: 1 1 auto; min-width: 0; }
header.site p { margin: .25rem 0 0; color: var(--muted); }
.site-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.site-title-row .btn { flex: 0 0 auto; }
.signout {
  display: flex; align-items: center; gap: .75rem; flex: 0 0 auto;
  color: var(--muted); font-size: .85rem;
}
.login-wrap { max-width: 460px; }
.settings-wrap { max-width: 640px; }
.legal { max-width: 720px; }
.legal .card h2 { margin: 1.6rem 0 .5rem; font-size: 1.02rem; }
.legal .card p, .legal .card li { line-height: 1.6; }
.legal .card ul { padding-left: 1.2rem; }
.legal .card li { margin-bottom: .5rem; }
.legal .card a, .legal-foot a { color: var(--accent); }
.legal-foot { text-align: center; color: var(--muted); font-size: .85rem; }
.legal-foot + .legal-foot { margin-top: -.4rem; }
.notice {
  background: #f1f9f4; border: 1px solid #cfe6d6; color: var(--ok);
  border-radius: 8px; padding: .7rem 1rem; margin-bottom: 1rem; font-size: .9rem;
}
.settings-status { margin: 0 0 1rem; }
/* Each sentence on its own line(s). The path is balanced so it breaks into two
   even lines instead of leaving "Generate token." dangling on its own. */
.token-help span { display: block; text-wrap: pretty; }
.token-help span + span { margin-top: .35rem; }
.token-help .token-path { text-wrap: balance; }
.token-help strong { color: var(--ink); }
.admin-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.admin-table th, .admin-table td {
  text-align: left; padding: .55rem .6rem; border-bottom: 1px solid var(--line);
}
.admin-table th { color: var(--muted); font-size: .78rem; font-weight: 600; }
.admin-table tr:last-child td { border-bottom: 0; }
.admin-table a { color: var(--accent); font-weight: 600; text-decoration: none; }
.admin-table a:hover { text-decoration: underline; }
/* The client list keeps every row to a single line, whatever is in it. Column
   widths are fixed, so nothing can push the table wider than its card; text that
   does not fit is cut off with an ellipsis instead of wrapping. Users takes
   whatever width the other columns leave. */
.clients-table { table-layout: fixed; }
.clients-table th, .clients-table td {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.clients-table th:nth-child(1) { width: 26%; }
.clients-table th:nth-child(3) { width: 11%; }
.clients-table th:nth-child(4) { width: 12%; }
.clients-table th:nth-child(5) { width: 15%; }
.clients-table .more { color: var(--muted); margin-left: .35rem; }
.admin-actions { text-align: right; white-space: nowrap; }
.admin-actions form { display: inline-block; margin-left: .4rem; }
.admin-add { margin-top: 1.25rem; }
.admin-headbtns { display: flex; gap: .5rem; flex: 0 0 auto; }
.viewing-banner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.viewing-banner button { flex: 0 0 auto; }
.admin-savebar { display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
button.danger { background: #fff; color: var(--err); border-color: var(--err); }
button.danger:hover:not(:disabled) { background: var(--err); color: #fff; border-color: var(--err); }
.preview-ai-note { margin-top: 1.5rem; }
.preview-out { margin-top: 1.5rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.preview-out textarea { width: 100%; background: #fafbfc; }
.preview-tags { margin-top: 1rem; }
#config-reference { margin-top: 2rem; }
.ref-group { margin: 1.5rem 0 .4rem; font-size: .95rem; }
.ref-table { table-layout: fixed; }
.ref-table th:nth-child(1) { width: 24%; }
.ref-table th:nth-child(2) { width: 42%; }
.ref-table td { vertical-align: top; overflow-wrap: anywhere; }
.ref-table code, .login-note code { font-size: .85em; }
.ref-table .pill { margin-left: .25rem; }
.login-note a { color: var(--accent); font-weight: 600; }
.ref-example { margin-top: 1.5rem; }
.ref-example summary { cursor: pointer; font-weight: 600; margin-bottom: .6rem; }
.ref-example pre {
  background: #f4f6f8; border: 1px solid var(--line); border-radius: 8px;
  padding: .9rem 1rem; font-size: .78rem; line-height: 1.45;
  white-space: pre-wrap; overflow-wrap: anywhere; margin: 0;
}
.admin-row { grid-template-columns: 2fr 1fr 2fr; }
.row2.admin-row { grid-template-columns: 1fr 3fr; }
label.field.admin-check { display: flex; align-items: center; gap: .5rem; margin-top: 1.6rem; }
textarea.admin-config { width: 100%; font-size: .8rem; line-height: 1.45; }
.admin-errors { margin: .4rem 0 0; padding-left: 1.2rem; }
.login-note { margin: 0 0 1rem; color: var(--muted); }
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.25rem;
}
.card h2 { margin: 0 0 1rem; font-size: 1.1rem; }
label.field { display: block; margin-bottom: 1rem; font-weight: 600; font-size: .9rem; }
label.field input[type="text"],
label.field input[type="password"],
label.field input[type="file"],
label.field select,
textarea,
.linkrow input[type="text"], .linkrow input[type="url"],
.cta-slot input[type="text"], .cta-slot input[type="url"], .cta-slot select {
  display: block;
  width: 100%;
  margin-top: .3rem;
  padding: .5rem .65rem;
  font: inherit;
  font-weight: 400;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  color: var(--ink);
}
textarea { font-family: Consolas, "Cascadia Mono", monospace; font-size: .85rem; }
/* The package box mirrors YouTube Studio's description field so the text is
   previewed in the font it will actually be published in. */
textarea.yt-font {
  font-family: Roboto, Arial, "Helvetica Neue", Helvetica, sans-serif;
  font-size: .95rem;
  line-height: 1.45;
}
::placeholder { color: var(--placeholder); opacity: 1; font-weight: 400; }
/* The closed <select> box renders using the SELECT's own color, not the
   inline style on whichever <option> is currently shown — that inline style
   only applies inside the open dropdown list. So the placeholder look for
   "no link chosen yet" has to be toggled on the select itself. */
select.placeholder-selected { color: var(--placeholder); }
.row2 { display: grid; grid-template-columns: 1fr 2fr; gap: 1rem; }
/* Channel needs room for long names; Video ID is always short. Title takes the rest. */
/* Channel is sized so a long name (about 28 characters) keeps a gap before the
   dropdown arrow; anything narrower crams it. */
.row3 { display: grid; grid-template-columns: 1.08fr 0.52fr 2.4fr; gap: 1rem; align-items: start; }
@media (max-width: 760px) {
  .row2, .row3 { grid-template-columns: 1fr; }
}

/* Drag & drop upload zone */
.dropzone {
  border: 2px dashed var(--line);
  border-radius: 10px;
  background: #fbfcfd;
  padding: 1.75rem 1rem;
  text-align: center;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.dropzone:hover { border-color: var(--accent); background: #f7f9ff; }
.dropzone.dragover { border-color: var(--accent); background: #eef3ff; }
.dropzone .dz-main { font-weight: 600; margin: 0 0 .25rem; }
.dropzone .dz-sub { margin: 0; color: var(--muted); font-size: .85rem; }
.filelist { margin-top: .85rem; display: grid; gap: .5rem; }
.filerow {
  display: flex;
  align-items: center;
  gap: .75rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .5rem .75rem;
  background: #fff;
}
.filerow .fname {
  flex: 1;
  font-size: .88rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.filerow select { padding: .35rem .5rem; font: inherit; font-size: .85rem;
  border: 1px solid var(--line); border-radius: 6px; background: #fff; }
.filerow .remove, .cta-slot .remove {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--err);
  border-radius: 6px;
  background: var(--err);
  color: #fff;
  cursor: pointer;
  transition: background .15s, border-color .15s;
  /* The glyph is drawn with pseudo-element bars so it centres on the box
     rather than on the font's math axis, which sits above centre. */
  font-size: 0;
  line-height: 0;
  position: relative;
}
.filerow .remove::before, .filerow .remove::after,
.cta-slot .remove::before, .cta-slot .remove::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 2px;
  background: currentColor;
  border-radius: 1px;
}
.filerow .remove::before, .cta-slot .remove::before {
  transform: translate(-50%, -50%) rotate(45deg);
}
.filerow .remove::after, .cta-slot .remove::after {
  transform: translate(-50%, -50%) rotate(-45deg);
}
.filerow .remove:hover, .cta-slot .remove:hover {
  background: #a5301f;
  border-color: #a5301f;
}
/* the select inside a slot head shares the row with the remove button */
.cta-slot .slothead select { margin-top: 0; }

/* CTA review modal */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 26, 35, .55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  z-index: 50;
}
.modal-backdrop[hidden] { display: none; }
.modal {
  background: var(--card);
  border-radius: 12px;
  box-shadow: 0 18px 48px rgba(15, 22, 33, .28);
  width: 100%;
  max-width: 680px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}
.modal .modal-head {
  padding: 1.25rem 1.5rem .85rem;
  border-bottom: 1px solid var(--line);
}
.modal .modal-head h3 { margin: 0 0 .3rem; font-size: 1.15rem; }
.modal .modal-head p { margin: 0; color: var(--muted); font-size: .87rem; }
.modal .modal-body { padding: 1.1rem 1.5rem; overflow-y: auto; }
.modal .modal-foot {
  padding: .9rem 1.5rem 1.25rem;
  border-top: 1px solid var(--line);
  display: flex;
  gap: .6rem;
  justify-content: flex-end;
}
/* Bold label style shared by each CTA link's name and the "Video Slug" label —
   same weight/size wherever it's used, per the modal's visual hierarchy. */
.cta-label {
  display: block;
  font-weight: 700;
  font-size: .9rem;
  margin-bottom: .35rem;
}
/* Section headers ("CTA Text") match the "Video Slug" label's weight/size so
   they don't compete visually with the modal title or the link cards. */
.modal-section-label {
  font-size: .9rem;
  font-weight: 700;
  margin: 0 0 .6rem;
}

/* Each CTA link gets its own card so it reads as one distinct unit. */
.cta-editor {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 1rem 1.1rem;
  margin-bottom: 1rem;
  background: #fff;
}
.cta-editor:last-child { margin-bottom: 0; }
.cta-editor .cta-label { margin-bottom: .65rem; }
.cta-editor textarea {
  width: 100%;
  font-family: "Segoe UI", system-ui, sans-serif;
  font-size: .9rem;
  padding: .55rem .65rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  resize: vertical;
}
.cta-editor .cta-count { font-size: .75rem; color: var(--muted); margin-top: .2rem; }
.cta-editor textarea[readonly] { background: #f4f6f8; color: var(--muted); }
.cta-editor .cta-status { margin-top: .55rem; font-size: .82rem; }
.cta-editor .cta-status.muted { color: var(--muted); }

/* Short link / destination shown as their own labeled, subtly-boxed chips. */
.link-chip {
  margin-top: .55rem;
  background: #f7f8fa;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .45rem .65rem;
}
.link-chip-label {
  font-size: .7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--muted);
  margin-bottom: .15rem;
}
.link-chip-value {
  font-size: .78rem;
  color: var(--ink);
  word-break: break-all;
}
/* The Bitly link is the one the user actually shares, so it gets a green tint
   to stand out from the plain destination-URL chip below it. */
.link-chip-bitly {
  background: #eaf7ee;
  border-color: #bfe3c9;
}
.link-chip-bitly .link-chip-label { color: var(--ok); }
/* Not created yet — same red used for error boxes elsewhere in the app. */
.link-chip-danger {
  background: #fdecea;
  border-color: #f5c6c1;
}
.link-chip-danger .link-chip-label { color: var(--err); }

/* shared slug field at the top of the modal */
.slug-row {
  border-bottom: 1px solid var(--line);
  padding-bottom: 1rem;
  margin-bottom: 1.1rem;
}
.slug-row input {
  width: 100%;
  margin-top: .25rem;
  padding: .5rem .65rem;
  font-family: Consolas, "Cascadia Mono", monospace;
  font-size: .85rem;
  border: 1px solid var(--line);
  border-radius: 6px;
}
.slug-row .slug-note { margin-top: .3rem; font-size: .75rem; color: var(--muted); }
.modal-status { flex: 1; font-size: .84rem; color: var(--muted); text-align: left; }

/* created / locked links */
.lock { font-size: .75rem; font-weight: 600; color: var(--ok); margin-left: .4rem; }
.pill {
  /* inline-flex + line-height:1, not just padding, so the text sits centred
     regardless of the inherited line-height's half-leading — the same class
     of fix used for the X glyph in the remove buttons. */
  display: inline-flex;
  align-items: center;
  line-height: 1;
  font-size: .7rem; font-weight: 600; color: var(--muted);
  border: 1px solid var(--line); border-radius: 999px;
  padding: .25rem .55rem; margin-left: .4rem;
}
/* Same solid red as the remove (X) buttons elsewhere in the app. */
.pill-danger {
  color: #fff;
  background: var(--err);
  border-color: var(--err);
}
/* Same green used for the "locked" / success states elsewhere in the app. */
.pill-success {
  color: #fff;
  background: var(--ok);
  border-color: var(--ok);
}
.bitly-plan.locked { background: #f7fbf8; border-color: #cfe6d6; }

/* Bitly's own tag-pill look, reused for the label(s) applied to each link. */
.tag-row { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .75rem; }
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  background: #f1f2f4;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .25rem .65rem;
  font-size: .78rem;
  font-weight: 500;
  color: var(--ink);
}
.tag-chip svg { flex: 0 0 auto; color: var(--muted); }
#pendingnotice { margin-bottom: 1rem; }
#linkwarn {
  margin-top: .75rem;
  background: #fdecea;
  border-color: #f5c6c1;
  color: var(--err);
  display: flex;
  align-items: center;
  gap: .75rem;
}
#linkwarn .warnicon { flex: 0 0 auto; width: 34px; height: 34px; }
#linkwarn .warnicon path { fill: var(--err); }
#linkwarn .warnicon rect, #linkwarn .warnicon circle { fill: #fff; }
#linkwarn .warnmsg { flex: 1 1 auto; }
#linkwarn code {
  font-size: .8rem;
  font-weight: 700;
  word-break: break-all;
  background: var(--err);
  color: #fff;
  padding: .05rem .3rem;
  border-radius: 4px;
}
#linkwarn button {
  flex: 0 0 auto;
  padding: .3rem .7rem;
  font-size: .82rem;
  border-color: var(--err);
  color: var(--err);
}
#linkwarn button:hover:not(:disabled) {
  background: var(--err);
  border-color: var(--err);
  color: #fff;
}

/* CTA link slots */
.cta-slot {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .75rem 1rem;
  margin-bottom: .75rem;
  background: #fff;
}
.cta-slot .slothead { display: flex; align-items: center; gap: .6rem; }
.cta-slot .slothead select { flex: 1; }
.cta-slot .slotbody { margin-top: .6rem; display: grid; gap: .5rem; }
.cta-slot label.sublabel {
  font-size: .78rem; font-weight: 600; color: var(--muted);
  display: block; margin-bottom: .15rem;
}
.warn {
  background: #fff8e6;
  border: 1px solid #f0d9a0;
  color: #8a6100;
  border-radius: 8px;
  padding: .7rem .9rem;
  margin-top: .9rem;
  font-size: .88rem;
}
.warn.banner { margin: 0 0 1.25rem; }
.warn a { color: inherit; font-weight: 600; }
/* Inline form validation */
.formerror {
  background: #fdecea;
  border: 1px solid #f5c6c1;
  color: var(--err);
  border-radius: 8px;
  padding: .7rem .9rem;
  margin-bottom: .9rem;
  font-size: .9rem;
  font-weight: 600;
}
.formerror[hidden] { display: none; }
.invalid,
input.invalid, select.invalid {
  border-color: var(--err) !important;
  box-shadow: 0 0 0 3px rgba(192, 57, 43, .12);
}
.dropzone.invalid { border-color: var(--err); background: #fdf3f2; }

.note {
  background: #eef4ff;
  border: 1px solid #cfdefb;
  color: #23438f;
  border-radius: 8px;
  padding: .7rem .9rem;
  margin-bottom: 1rem;
  font-size: .88rem;
}
.linkrow {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .75rem 1rem;
  margin-bottom: .75rem;
}
.linkrow .linkhead { display: flex; align-items: center; gap: .5rem; font-weight: 600; }
.linkrow .linkbody { margin-top: .6rem; display: grid; gap: .5rem; }
.linkrow .hint { color: var(--muted); font-size: .8rem; }
button, .btn {
  display: inline-block;
  font: inherit;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: 6px;
  padding: .55rem 1.1rem;
  cursor: pointer;
  font-weight: 600;
  text-decoration: none;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
button.secondary, .btn.secondary {
  background: #fff;
  color: var(--accent);
}
/* Secondary buttons fill blue on hover so a click is unmistakable. */
button:hover:not(:disabled), .btn:hover {
  background: #1c46b0;
  border-color: #1c46b0;
  color: #fff;
}
button:active:not(:disabled) {
  background: #16358f;
  border-color: #16358f;
  color: #fff;
  transform: translateY(1px);
}
button:focus-visible {
  outline: 3px solid rgba(36, 86, 214, .35);
  outline-offset: 2px;
}
button:disabled { opacity: .5; cursor: default; }
/* Remove buttons keep their red identity through hover and press. */
.filerow .remove:active, .cta-slot .remove:active {
  background: #8c2818;
  border-color: #8c2818;
  color: #fff;
}
.toolbar { display: flex; gap: .5rem; margin: .5rem 0 0; flex-wrap: wrap; }
.error {
  background: #fdecea;
  border: 1px solid #f5c6c1;
  color: var(--err);
  border-radius: 8px;
  padding: .75rem 1rem;
  margin-bottom: 1rem;
}
.status-ok { color: var(--ok); font-weight: 600; }
.status-err { color: var(--err); font-weight: 600; }
.bitly-plan { border: 1px solid var(--line); border-radius: 8px; padding: .85rem 1rem; margin-bottom: .85rem; }
.bitly-plan .planhead { font-weight: 700; margin-bottom: .5rem; }
.bitly-plan .result { margin-top: .4rem; font-size: .9rem; }
.charcount { color: var(--muted); font-size: .8rem; }
.charcount.over { color: var(--err); font-weight: 700; }
.muted { color: var(--muted); }
.small { font-size: .85rem; }
/* Progress indicator shown below the submit button while generating */
.progress {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin-top: .85rem;
  color: var(--muted);
  font-size: .9rem;
}
.progress[hidden] { display: none; }
.wheel {
  width: 16px;
  height: 16px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .8s linear infinite;
  flex: 0 0 auto;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .wheel { animation-duration: 2.4s; }
}

/* Inline spinner used by the Bitly button on the result page */
.spinner {
  display: none;
  margin-left: .6rem;
  color: var(--muted);
  font-weight: 400;
}
.working .spinner { display: inline; }
