/* AACPOJ user profile (/user/<name>/) — card-based redesign 2026-05-12.
   Coexists with DMOJ's user-info-page layout: this template overrides
   {% block body %} entirely, so the side-by-side sidebar layout from
   user-base.html is bypassed for /user/. */

.profile-page {
  --profile-bg: #ffffff;
  --profile-border: #e7e5e4;
  --profile-border-soft: #f1efed;
  --profile-text: #1c1917;
  --profile-text-soft: #57534e;
  --profile-text-muted: #a8a29e;
  --profile-radius: 16px;
  --profile-radius-sm: 10px;
  --profile-shadow: 0 1px 2px rgba(15,23,42,.04), 0 1px 3px rgba(15,23,42,.06);

  max-width: 1180px;
  margin: 32px auto 64px;
  padding: 0 20px;
  display: grid;
  gap: 24px;
  color: var(--profile-text);
  font-family: 'Noto Sans TC', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
}

/* --- HERO CARD ------------------------------------------- */
.profile-hero {
  background: var(--profile-bg);
  border: 1px solid var(--profile-border);
  border-radius: var(--profile-radius);
  padding: 32px;
  display: grid;
  grid-template-columns: 144px 1fr;
  gap: 28px;
  align-items: start;
  box-shadow: var(--profile-shadow);
}

.profile-avatar {
  width: 144px;
  height: 144px;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid var(--brand-light, #EAFBF7);
  box-shadow: 0 4px 10px rgba(0, 168, 150, 0.12);
}

.profile-identity {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.profile-name-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.profile-username {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--profile-text);
  margin: 0;
  line-height: 1.1;
}

.profile-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  letter-spacing: 0.01em;
}

.profile-chip--level {
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
  border: 1px solid rgba(0, 168, 150, 0.25);
}
.profile-chip--teacher {
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fde68a;
}
.profile-chip--admin {
  background: #ede9fe;
  color: #5b21b6;
  border: 1px solid #ddd6fe;
}
.profile-chip--lost {
  background: #f3f4f6;
  color: #57534e;
  border: 1px solid #e7e5e4;
}

.profile-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-left: auto;
}

.profile-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid var(--profile-border);
  background: #fff;
  color: var(--profile-text-soft);
  cursor: pointer;
  transition: all 0.15s ease;
}
.profile-action-btn:hover {
  border-color: var(--brand, #00A896);
  color: var(--brand-dark, #028090);
  background: var(--brand-light, #EAFBF7);
}
.profile-action-btn--primary {
  border-color: var(--brand, #00A896);
  background: var(--brand, #00A896);
  color: #fff;
}
.profile-action-btn--primary:hover {
  background: var(--brand-dark, #028090);
  border-color: var(--brand-dark, #028090);
  color: #fff;
}

/* Admin dropdown — <details>/<summary> styled identically to .profile-action-btn
   (white bg, 1px gray border, brand hover). Strip browser-default focus ring
   and disclosure triangle so it matches the sibling "Edit profile" button.   */
.profile-admin-menu {
  position: relative;
}
.profile-admin-menu summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.profile-admin-menu summary::-webkit-details-marker { display: none; }
.profile-admin-menu summary::marker { content: ''; }
.profile-admin-menu summary:focus { outline: none; }
.profile-admin-menu summary:focus-visible {
  outline: 2px solid var(--brand-dark, #028090);
  outline-offset: 2px;
}
.profile-admin-menu-items {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  background: #fff;
  border: 1px solid var(--profile-border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15,23,42,.12);
  min-width: 200px;
  padding: 4px;
  z-index: 50;
}
.profile-admin-menu-items a {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  color: var(--profile-text-soft);
  text-decoration: none;
}
.profile-admin-menu-items a:hover {
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
}
.profile-admin-menu-items a i { width: 14px; opacity: 0.7; }

.profile-about {
  font-size: 15px;
  line-height: 1.7;
  color: var(--profile-text-soft);
  margin-top: 4px;
}
.profile-about p { margin: 0 0 8px; }
.profile-about p:last-child { margin-bottom: 0; }

/* Tame markdown rendering inside the bio so a casual `***text***\n----` —
   which markdown turns into <h2><strong><em>text</em></strong></h2> —
   doesn't look like a screaming title. Headings inherit body sizing.
   Also disable synthesized italic: Noto Sans TC has no italic variant
   so the browser shears regular glyphs to fake it (ugly on Han chars).
   `font-synthesis: weight` keeps bold synthesis working but turns off
   italic synthesis — Latin runs still use Inter italic which is real. */
.profile-about {
  font-synthesis: weight;
}
.profile-about h1,
.profile-about h2,
.profile-about h3,
.profile-about h4,
.profile-about h5,
.profile-about h6 {
  font-size: inherit;
  font-weight: 600;
  line-height: 1.5;
  margin: 8px 0 4px;
  color: var(--profile-text);
}
.profile-about ul, .profile-about ol { padding-left: 1.5em; margin: 4px 0 8px; }
.profile-about a { color: var(--brand-dark, #028090); }
.profile-about code {
  background: #eef2f1;
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 0.9em;
}
.profile-about pre {
  background: #f6f8fa;
  padding: 10px 12px;
  border-radius: 6px;
  overflow-x: auto;
}
.profile-about hr { border: 0; border-top: 1px solid var(--profile-border, #e7e5e4); margin: 8px 0; }
.profile-about-empty {
  font-style: italic;
  color: var(--profile-text-muted);
}

/* --- STATS (3 cards) ------------------------------------- */
.profile-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.stat-card {
  background: var(--profile-bg);
  border: 1px solid var(--profile-border);
  border-radius: var(--profile-radius);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
  box-shadow: var(--profile-shadow);
  position: relative;
  overflow: hidden;
}
.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: linear-gradient(90deg, var(--brand, #00A896), var(--brand-dark, #028090));
  opacity: 0.85;
}
.stat-card-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--profile-text-muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
.stat-card-label i { color: var(--brand, #00A896); }
.stat-card-value {
  font-size: 36px;
  font-weight: 700;
  color: var(--profile-text);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.stat-card-unit {
  font-size: 14px;
  font-weight: 500;
  color: var(--profile-text-muted);
}

/* --- MAIN + SIDE GRID ------------------------------------ */
.profile-grid {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 24px;
  align-items: start;
}

.profile-card {
  background: var(--profile-bg);
  border: 1px solid var(--profile-border);
  border-radius: var(--profile-radius);
  padding: 24px;
  box-shadow: var(--profile-shadow);
}
.profile-card-title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--profile-text-muted);
  margin: 0 0 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.profile-card-title i { color: var(--brand, #00A896); }
.profile-card + .profile-card { margin-top: 16px; }

/* --- ACTIVITY HEATMAP ------------------------------------
   Layout overhaul 2026-05-12 (v2):
     * Year nav moved inline with the card title (chevron icons + pill)
     * Cells gain breathing room via border-spacing
     * Day labels: only M / W / F visible
   NOTE on specificity: DMOJ's resources/users.scss uses
   `#submission-activity #submission-activity-display table td.activity-N`
   (specificity 2-1-2). To win without `!important`, every override below
   carries `.profile-activity-card #submission-activity ...` (>= 2 IDs + 1
   class so we beat the base in classes-tiebreak).                          */
.profile-activity-card { padding: 22px 24px 20px; }

.profile-activity-card .activity-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.profile-activity-card .activity-header .profile-card-title {
  margin: 0;
}
.profile-activity-card #submission-activity {
  display: block !important; /* JS sets style=display:none initially; no other safe way to flip */
}
.profile-activity-card #submission-activity-header {
  font-size: 12px;
  font-weight: 500;
  color: var(--profile-text-muted);
  margin: 0 0 12px;
  letter-spacing: 0.01em;
}

/* Year nav — beats DMOJ's `#submission-activity #submission-activity-actions a`
   (2 IDs + 1 tag = spec 2-0-1) using 1 class + 2 IDs + 1 tag = 2-1-1.       */
.profile-activity-card #submission-activity #submission-activity-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
  color: var(--profile-text-soft);
  text-align: left;          /* override DMOJ text-align: center */
}
.profile-activity-card #submission-activity #submission-activity-actions a {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: var(--profile-text-muted);
  background: transparent;
  border: none;
  text-decoration: none;
  transition: all 0.15s ease;
  font-size: 11px;            /* override DMOJ font-size: 1.75em */
  padding: 0;
  cursor: pointer;
}
.profile-activity-card #submission-activity #submission-activity-actions a:hover {
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
}
.profile-activity-card #submission-activity #submission-activity-actions a:focus {
  outline: none;
}
.profile-activity-card #submission-activity #submission-activity-actions a:focus-visible {
  outline: 2px solid var(--brand-dark, #028090);
  outline-offset: 2px;
}
.profile-activity-card #submission-activity #submission-activity-actions a:active {
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
  transform: none;            /* don't inherit any global button:active translateY */
}
.profile-activity-card #submission-activity #submission-activity-actions #prev-year-action,
.profile-activity-card #submission-activity #submission-activity-actions #next-year-action {
  font-size: 11px;            /* DMOJ targets these with 1.75em — beat it */
}
.profile-activity-card #submission-activity #submission-activity-actions #year {
  display: inline-block;
  padding: 4px 14px;
  border-radius: 999px;
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
  font-variant-numeric: tabular-nums;
  font-size: 12px;            /* DMOJ targets with 1.25em — beat it */
  font-weight: 600;
  min-width: 72px;
  text-align: center;
  letter-spacing: 0.02em;
}

/* Heatmap container — DMOJ adds `border: 1px solid #ccc; border-radius: 6px`
   plus internal padding. We're inside our own card; strip that completely. */
.profile-activity-card #submission-activity #submission-activity-display {
  border: none;
  border-radius: 0;
  padding: 0;
  overflow-x: auto;
}

/* Cells — beats DMOJ td.activity-N (2 IDs + 1 class + 2 tags = 2-1-2) with
   1 class + 2 IDs + 1 class + 2 tags = 2-2-2. Also override DMOJ's
   `width: 100%; padding: 5px` so the grid sizes to content (cells stay
   12px wide and align left, not stretched across the whole card).         */
.profile-activity-card #submission-activity #submission-activity-display table {
  margin: 0;
  padding: 0;
  width: auto;
  border-collapse: separate;
  border-spacing: 3px;
}
.profile-activity-card #submission-activity #submission-activity-display table td {
  width: 16px;
  height: 16px;
  border-radius: 3px;
  padding: 0;
  transition: outline-color 0.12s ease;
  outline: 2px solid transparent;
  outline-offset: 1px;
}
.profile-activity-card #submission-activity #submission-activity-display table td:hover {
  outline-color: var(--brand-dark, #028090);
}
.profile-activity-card #submission-activity #submission-activity-display table td.activity-blank {
  background: transparent;
  outline: none;
}
/* Month boundary spacer column — emitted by user_profile.js between weeks
   whose Sunday-of-the-week falls in different months. Looks like a thin
   vertical gap so months read distinctly.                                  */
.profile-activity-card #submission-activity #submission-activity-display table td.month-separator {
  width: 6px;
  background: transparent;
  outline: none;
  border-radius: 0;
  pointer-events: none;
}
/* Month label row underneath the heatmap — one <td> per month spanning
   that month's weeks via colspan, plus an empty .month-sep-spacer cell to
   line up with the inter-month separator column.                          */
.profile-activity-card #submission-activity #submission-activity-display table tr#month-labels-row td {
  font-size: 10px;
  font-weight: 600;
  color: var(--profile-text-muted);
  text-align: left;
  padding: 6px 0 0;
  background: transparent;
  outline: none;
  border-radius: 0;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  height: auto;
  width: auto;
  vertical-align: top;
}
.profile-activity-card #submission-activity #submission-activity-display table tr#month-labels-row td.month-sep-spacer {
  width: 6px;
  padding: 0;
}
.profile-activity-card #submission-activity #submission-activity-display table tr#month-labels-row td:hover {
  outline: none;
}
/* Brand-anchored gradient — level 3 = exact brand #00A896 (was #1bab9c, an
   off-brand teal that looked desaturated next to the rest of the page).    */
.profile-activity-card #submission-activity #submission-activity-display table td.activity-0 { background: #eef2f1; }
.profile-activity-card #submission-activity #submission-activity-display table td.activity-1 { background: #c2ebe5; }
.profile-activity-card #submission-activity #submission-activity-display table td.activity-2 { background: #66cabd; }
.profile-activity-card #submission-activity #submission-activity-display table td.activity-3 { background: #00A896; }
.profile-activity-card #submission-activity #submission-activity-display table td.activity-4 { background: #006d61; }

/* Day labels — DMOJ has `@media (max-width:1000px) { ...th.submission-date-col
   { display: none } }`. Our activity card sits inside the 2-col grid's main
   side, well under 1000px on any viewport, so we MUST explicitly set
   display:table-cell here (otherwise the entire label column collapses).   */
.profile-activity-card #submission-activity #submission-activity-display table th,
.profile-activity-card #submission-activity #submission-activity-display table th.submission-date-col {
  display: table-cell;
  width: auto;
  font-size: 10px;
  color: var(--profile-text-muted);
  font-weight: 600;
  padding-right: 8px;
  text-align: right;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
}
/* Per Anna 2026-05-12: show all 7 weekday labels (Sun..Sat), no longer
   hiding alternating rows. */

/* Footer (total count + legend) */
.profile-activity-card #submission-activity #submission-activity-display .info-bar {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--profile-border-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: var(--profile-text-muted);
  gap: 12px;
}
.profile-activity-card #submission-activity #submission-total-count {
  font-weight: 500;
  color: var(--profile-text-soft);
  font-variant-numeric: tabular-nums;
  padding-left: 0;          /* DMOJ sets `padding-left: 8%` */
  font-size: 12px;          /* DMOJ sets `font-size: 0.85em` */
  align-self: auto;
}
.profile-activity-card #submission-activity #submission-activity-display table.info-table {
  margin: 0;
  border-collapse: separate;
  border-spacing: 2px;
}
.profile-activity-card #submission-activity #submission-activity-display table.info-table td {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  padding: 0;
}
.profile-activity-card #submission-activity #submission-activity-display table.info-table td.activity-0 { background: #eef2f1; }
.profile-activity-card #submission-activity #submission-activity-display table.info-table td.activity-1 { background: #c2ebe5; }
.profile-activity-card #submission-activity #submission-activity-display table.info-table td.activity-2 { background: #66cabd; }
.profile-activity-card #submission-activity #submission-activity-display table.info-table td.activity-3 { background: #00A896; }
.profile-activity-card #submission-activity #submission-activity-display table.info-table td.activity-4 { background: #006d61; }
.profile-activity-card #submission-activity .info-table-text {
  padding: 0 8px;
  font-weight: 500;
  letter-spacing: 0.02em;
}

/* DMOJ's `.tooltipped` shows aria-label on hover. The arrow + dark bg can
   look a bit off on a white card, but we leave it for now since the cell
   hover ring already gives visual feedback. */

/* --- SIDE CARDS ------------------------------------------ */
.profile-side {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.profile-link-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.profile-link-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  text-decoration: none;
  color: var(--profile-text);
  font-size: 14px;
  font-weight: 500;
  transition: background 0.12s ease;
}
.profile-link-item:hover {
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
}
.profile-link-item i {
  color: var(--brand, #00A896);
  width: 16px;
  font-size: 14px;
}
.profile-link-item .meta {
  margin-left: auto;
  font-size: 12px;
  color: var(--profile-text-muted);
  font-weight: 500;
}

.profile-courses-list,
.profile-classes-list,
.profile-oj-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.profile-course-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 14px;
  color: var(--profile-text);
  text-decoration: none;
}
.profile-course-item:hover {
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
}
/* Non-clickable variant for course names — /course/<id>/ requires
   course-admin perms, so don't dangle a link the average viewer can't open. */
.profile-course-item.profile-course-item--static {
  cursor: default;
  color: var(--profile-text);
}
.profile-course-item.profile-course-item--static:hover {
  background: transparent;
  color: var(--profile-text);
}
.profile-course-item .meta {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
  font-variant-numeric: tabular-nums;
}

.profile-empty-row {
  font-size: 13px;
  color: var(--profile-text-muted);
  font-style: italic;
  padding: 6px 10px;
}

.profile-oj-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 14px;
}
.profile-oj-row + .profile-oj-row { border-top: 1px solid var(--profile-border-soft); }
.profile-oj-row .oj-name {
  font-weight: 600;
  color: var(--profile-text);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.profile-oj-row .oj-handle {
  color: var(--brand-dark, #028090);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.profile-oj-row .oj-handle:hover { text-decoration: underline; }

/* Admin notes (staff-only) */
.profile-admin-notes pre {
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: var(--profile-radius-sm);
  padding: 12px;
  font-size: 13px;
  color: #78350f;
  white-space: pre-wrap;
  margin: 0;
  max-height: 240px;
  overflow-y: auto;
}

/* --- RECENT SUBMISSIONS (self / superuser only) ---------- */
.profile-recent-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.profile-recent-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 13px;
  text-decoration: none;
  color: var(--profile-text);
}
.profile-recent-row:hover { background: var(--brand-light, #EAFBF7); }
.profile-recent-row .verdict {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  min-width: 32px;
  text-align: center;
  flex-shrink: 0;
}
.profile-recent-row .verdict-AC { background: #d1fae5; color: #065f46; }
.profile-recent-row .verdict-WA { background: #fee2e2; color: #991b1b; }
.profile-recent-row .verdict-TLE,
.profile-recent-row .verdict-MLE,
.profile-recent-row .verdict-OLE { background: #fef3c7; color: #92400e; }
.profile-recent-row .verdict-CE,
.profile-recent-row .verdict-RTE,
.profile-recent-row .verdict-IE,
.profile-recent-row .verdict-AB { background: #e5e7eb; color: #374151; }
.profile-recent-row .problem-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}
.profile-recent-row .time {
  font-size: 11px;
  color: var(--profile-text-muted);
  font-variant-numeric: tabular-nums;
}

/* --- RESPONSIVE ------------------------------------------ */
@media (max-width: 1024px) {
  .profile-grid {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 720px) {
  .profile-hero {
    grid-template-columns: 1fr;
    text-align: center;
    padding: 24px;
  }
  .profile-avatar {
    margin: 0 auto;
    width: 120px;
    height: 120px;
  }
  .profile-name-row {
    justify-content: center;
  }
  .profile-actions {
    margin-left: 0;
    margin-top: 8px;
    justify-content: center;
  }
  .profile-stats {
    grid-template-columns: 1fr;
  }
  .stat-card { padding: 18px; }
  .stat-card-value { font-size: 30px; }
  .profile-page { padding: 0 12px; margin-top: 16px; }
}

/* === SETTINGS PAGE (/settings/) — shares the profile card aesthetic ====== */
.settings-page {
  max-width: 760px;
  margin: 32px auto 64px;
  padding: 0 20px;
  font-family: 'Noto Sans TC', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  color: var(--profile-text, #1c1917);
}

.settings-header {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;       /* the tabs/panel sit flush below */
}
.settings-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
  color: #57534e;
  text-decoration: none;
  width: fit-content;
}
.settings-back:hover { color: var(--brand-dark, #028090); }
.settings-back i { font-size: 11px; }
.settings-title {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
  color: #1c1917;
}

.settings-card {
  background: #fff;
  border: 1px solid #e7e5e4;
  border-radius: 16px;
  padding: 24px;
  box-shadow: 0 1px 2px rgba(15,23,42,.04), 0 1px 3px rgba(15,23,42,.06);
}
.settings-card-title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #a8a29e;
  margin: 0 0 6px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.settings-card-title i { color: var(--brand, #00A896); }
.settings-card-hint {
  font-size: 13px;
  color: #78716c;
  margin: 0 0 16px;
  line-height: 1.5;
}

.settings-alert {
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 12px;
  padding: 12px 16px;
  color: #991b1b;
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.settings-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px 24px;
}
.settings-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.settings-field-label {
  font-size: 13px;
  font-weight: 600;
  color: #44403c;
}
.settings-field-hint {
  font-size: 11px;
  color: #a8a29e;
  margin-bottom: 4px;
  line-height: 1.4;
}
.settings-field select,
.settings-field input[type="text"],
.settings-field input[type="number"] {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid #e7e5e4;
  border-radius: 8px;
  font-size: 13px;
  font-family: inherit;
  background: #fff;
  transition: border-color 0.15s ease;
  box-sizing: border-box;
}
.settings-field select:focus,
.settings-field input:focus {
  outline: none;
  border-color: var(--brand, #00A896);
}

.settings-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #44403c;
  cursor: pointer;
}
.settings-checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--brand, #00A896);
  margin: 0;
}

.settings-submit-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}

.settings-link-list { display: flex; flex-direction: column; gap: 4px; }
.settings-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 10px;
  text-decoration: none;
  color: #1c1917;
  transition: background 0.12s ease;
}
.settings-link:hover { background: var(--brand-light, #EAFBF7); color: var(--brand-dark, #028090); }
.settings-link i { color: var(--brand, #00A896); width: 18px; font-size: 14px; }
.settings-link-label { display: block; font-size: 14px; font-weight: 500; }
.settings-link-hint { display: block; font-size: 11px; color: #a8a29e; margin-top: 2px; }

.settings-template-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.settings-template-toolbar select {
  padding: 6px 12px;
  border: 1px solid #e7e5e4;
  border-radius: 8px;
  font-size: 13px;
  background: #fff;
}
.settings-template-status {
  font-size: 12px;
  color: var(--brand-dark, #028090);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.settings-template-status.visible { opacity: 1; }
.settings-template-editor {
  width: 100%;
  height: 280px;
  border: 1px solid #e7e5e4;
  border-radius: 10px;
  overflow: hidden;
}

/* About-textarea sizing — DMOJ's pagedown widget puts its own wrapper. */
.settings-card textarea {
  width: 100%;
  min-height: 140px;
  padding: 10px 12px;
  border: 1px solid #e7e5e4;
  border-radius: 8px;
  font-family: inherit;
  font-size: 13px;
  resize: vertical;
  box-sizing: border-box;
}
.settings-card textarea:focus {
  outline: none;
  border-color: var(--brand, #00A896);
}

@media (max-width: 720px) {
  .settings-page { max-width: 100%; padding: 0 12px; margin-top: 16px; }
  .settings-grid-2 { grid-template-columns: 1fr; }
  .settings-title { font-size: 24px; }
}

/* DMOJ pagedown widget's "Update preview" button — DMOJ defaults to a gray
   `#ccc` bar that clashes with our card aesthetic. Restyle to match the
   brand-light/brand-dark "secondary action" look used elsewhere on /settings/.
   Specificity 0-2-1 beats DMOJ's `div.dmmd-preview-update` (0-1-1).         */
.settings-card div.dmmd-preview-update {
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
  border: 1px solid rgba(0, 168, 150, 0.25);
  border-radius: 8px;
  height: auto;
  line-height: 1;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  transition: all 0.15s ease;
  margin-top: 8px;
}
.settings-card div.dmmd-preview-update:hover {
  background: var(--brand, #00A896);
  color: #fff;
  border-color: var(--brand, #00A896);
}
.settings-card div.dmmd-preview-update i {
  margin-right: 6px;
  font-size: 12px;
}
/* When the preview has content, DMOJ rounds top corners only — keep our
   border-radius consistent on top, square on bottom (joins seamlessly with
   the preview content block below).                                       */
.settings-card div.dmmd-preview.dmmd-preview-has-content div.dmmd-preview-update {
  border-radius: 8px 8px 0 0;
  border-bottom: none;
}
.settings-card div.dmmd-preview.dmmd-preview-has-content div.dmmd-preview-content {
  border: 1px solid rgba(0, 168, 150, 0.25);
  border-top: none;
  border-radius: 0 0 8px 8px;
  padding: 12px 14px;
}

/* === SETTINGS TABS (bookmark/folder-tab style) ==========================
   Tabs sit ABOVE the content panel like physical folder tabs:
     * Each tab has rounded top corners, no bottom border
     * Inactive tabs use a slightly darker background (paper behind)
     * Active tab matches the content panel background, with a brand-color
       top accent strip + a ::after pseudo that "punches through" the
       panel's top border so the tab visually merges into the content. */
.settings-tabs {
  display: flex;
  gap: 4px;
  margin: 8px 0 0;
  padding: 0 16px;
  overflow-x: auto;
  position: relative;
  z-index: 2;
}
.settings-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 20px 11px;
  background: #efeeed;
  border: 1px solid #e7e5e4;
  border-bottom: none;
  border-radius: 12px 12px 0 0;
  font-size: 13px;
  font-weight: 500;
  color: #78716c;
  text-decoration: none;
  white-space: nowrap;
  position: relative;
  transition: background 0.15s ease, color 0.15s ease;
}
.settings-tab:hover {
  background: #e6e5e3;
  color: var(--brand-dark, #028090);
}
.settings-tab.is-active {
  background: #fff;                            /* matches .settings-panel  */
  color: var(--brand-dark, #028090);
  font-weight: 700;
  padding-top: 8px;
  border-top: 3px solid var(--brand, #00A896); /* the brand-color spine    */
  z-index: 3;
}
/* `::after` overlays the panel's 1px top border under the active tab so
   the tab looks fused into the panel below.                              */
.settings-tab.is-active::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: #fff;
}
.settings-tab i { font-size: 13px; color: inherit; }

/* The content panel wraps all cards for the active tab and provides the
   top border that the active tab visually punches through.               */
.settings-panel {
  background: #fff;
  border-top: 1px solid #e7e5e4;
  padding: 24px 0 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: relative;
  z-index: 1;
}

/* === SETTINGS / OJ tab rows ============================================ */
.settings-oj-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.settings-oj-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 12px 16px;
  border: 1px solid #e7e5e4;
  border-radius: 10px;
  background: #fafafa;
}
.settings-oj-label {
  font-weight: 600;
  font-size: 14px;
  color: #1c1917;
  min-width: 110px;
}
.settings-oj-handle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  font-size: 13px;
}
.settings-oj-handle a {
  color: var(--brand-dark, #028090);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.settings-oj-handle a:hover { text-decoration: underline; }
.settings-oj-locked {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #a8a29e;
  font-weight: 500;
}
.settings-oj-input {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
}
.settings-oj-input input[type="text"] {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #e7e5e4;
  border-radius: 8px;
  font-size: 13px;
  background: #fff;
}
.settings-oj-input input[type="text"]:focus {
  outline: none;
  border-color: var(--brand, #00A896);
}
.settings-oj-cses-hint {
  flex-basis: 100%;
  font-size: 11px;
  color: #a8a29e;
  margin-top: 2px;
}

.settings-alert.settings-alert--warning {
  background: #fffbeb;
  border-color: #fde68a;
  color: #92400e;
}

/* === MARKDOWN EDITOR (About me — notes-style toolbar + split preview) ===
   Three modes — edit / split / preview — toggled by `data-mode` on
   `.md-body`. Mirrors notes/standalone_note_edit.html's `.sn-editor`     */
.md-editor {
  border: 1px solid #e7e5e4;
  border-radius: 10px;
  background: #fff;
  /* No `overflow: hidden` — that was clipping the syntax-button tooltips
     when they extended past the editor's top edge (especially the first
     button, whose centered tooltip reaches off the left side). Round the
     inner toolbar/body corners individually to preserve the visual frame.
   */
}
.md-editor > :first-child { border-top-left-radius: 10px; border-top-right-radius: 10px; }
.md-editor > :last-child { border-bottom-left-radius: 10px; border-bottom-right-radius: 10px; }
.md-editor-toolbar {
  display: flex;
  align-items: center;
  background: #f5f4f3;
  border-bottom: 1px solid #e7e5e4;
  padding: 6px 8px;
  gap: 2px;
}
.md-editor-toolbar .md-mode {
  padding: 6px 12px;
  border: none;
  background: none;
  cursor: pointer;
  font-size: 12px;
  color: #78716c;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 0.12s ease, color 0.12s ease;
}
.md-editor-toolbar .md-mode:hover { color: var(--brand-dark, #028090); }
.md-editor-toolbar .md-mode.is-active {
  background: #fff;
  color: #1c1917;
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}
.md-editor-toolbar .md-mode i { font-size: 11px; }
.md-editor-toolbar .md-spacer { flex: 1; }
.md-editor-toolbar .md-char-count {
  font-size: 11px;
  color: #a8a29e;
  font-variant-numeric: tabular-nums;
  padding-right: 4px;
}

/* Second toolbar row — markdown-syntax shortcut buttons. */
.md-editor-toolbar.md-editor-toolbar--syntax {
  border-top: 1px solid #e7e5e4;
  background: #fafaf9;
  padding: 4px 6px;
  gap: 1px;
}
.md-editor-toolbar .md-insert {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 26px;
  border: none;
  background: transparent;
  cursor: pointer;
  border-radius: 5px;
  color: #57534e;
  font-size: 13px;
  transition: background 0.12s ease, color 0.12s ease;
  padding: 0;
}
.md-editor-toolbar .md-insert:hover {
  background: var(--brand-light, #EAFBF7);
  color: var(--brand-dark, #028090);
}
.md-editor-toolbar .md-insert:active {
  background: var(--brand, #00A896);
  color: #fff;
}
.md-editor-toolbar .md-sep {
  width: 1px;
  height: 16px;
  background: #e7e5e4;
  margin: 0 4px;
}

/* Instant CSS tooltip on syntax-shortcut buttons. The native `title=` tip
   still works for screen readers / keyboard focus, but it has a ~1s delay
   and a small system-default look; this ::after gives an immediate brand-
   themed tooltip on hover. Covers both /settings/ (.md-insert) and /notes/
   (.sn-insert). The parent toolbar is `position: relative` so the absolute
   ::after stays within the editor frame.                                 */
.md-editor-toolbar { position: relative; }
.sn-toolbar { position: relative; }
.md-insert,
.sn-insert,
.sn-toolbar .insert-prob-btn {
  position: relative;
}
.md-insert[title]:hover::after,
.sn-insert[title]:hover::after,
.sn-toolbar .insert-prob-btn[title]:hover::after {
  content: attr(title);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: #1c1917;
  color: #fff;
  font-size: 11px;
  font-weight: 500;
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
  pointer-events: none;
  z-index: 100;
  font-family: 'JetBrains Mono', 'Noto Sans TC', sans-serif;
  letter-spacing: 0.01em;
  /* Small arrow underneath pointing at the button */
  box-shadow: 0 2px 4px rgba(0,0,0,0.15);
}
.md-insert[title]:hover::before,
.sn-insert[title]:hover::before,
.sn-toolbar .insert-prob-btn[title]:hover::before {
  content: '';
  position: absolute;
  bottom: calc(100% + 2px);
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: #1c1917;
  z-index: 100;
  pointer-events: none;
}

.md-body {
  display: flex;
  min-height: 320px;
}
.md-body textarea {
  flex: 1;
  border: none;
  padding: 12px 14px;
  font-size: 13px;
  line-height: 1.5;                       /* must match .md-gutter for row alignment */
  font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
  resize: vertical;
  outline: none;
  box-sizing: border-box;
  min-height: 320px;
  background: #fff;
}
/* Line-number gutter — rendered when {% include _markdown_editor.html %}
   is called with show_line_numbers=true.                                */
.md-body--gutter .md-gutter {
  flex: 0 0 auto;
  width: 36px;
  background: #f8f8f8;
  border-right: 1px solid #e7e5e4;
  padding: 12px 6px;                      /* match textarea padding-top */
  text-align: right;
  font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
  font-size: 12px;
  line-height: 1.5;                       /* match textarea line-height */
  color: #a8a29e;
  overflow: hidden;                        /* scrolled by JS to mirror textarea */
  user-select: none;
  box-sizing: border-box;
}
.md-body--gutter .md-gutter span { display: block; }
.md-body--gutter textarea { padding-left: 14px; }
/* Gutter belongs to the editor mode only; the preview pane has no
   sense of "lines", and showing the gutter in split mode next to the
   textarea is fine but in preview mode it should disappear.            */
.md-body[data-mode="preview"] .md-gutter { display: none; }

/* === Toolbar primary/action buttons (Save/Cancel right-end of toolbar)
   Used when the caller injects `extra_toolbar_right` (notes does this
   so the Save button shares the toolbar instead of needing its own
   bottom row).                                                        */
.md-editor-toolbar .md-toolbar-action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border: 1px solid var(--profile-border, #e7e5e4);
  background: #fff;
  color: var(--profile-text-soft, #57534e);
  font-size: 12px;
  font-weight: 600;
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
  margin-left: 6px;
  transition: all 0.15s ease;
}
.md-editor-toolbar .md-toolbar-action:hover {
  border-color: var(--brand, #00A896);
  color: var(--brand-dark, #028090);
  background: var(--brand-light, #EAFBF7);
}
.md-editor-toolbar .md-toolbar-action--primary {
  border-color: var(--brand, #00A896);
  background: var(--brand, #00A896);
  color: #fff;
}
.md-editor-toolbar .md-toolbar-action--primary:hover {
  background: var(--brand-dark, #028090);
  border-color: var(--brand-dark, #028090);
  color: #fff;
}
.md-editor-toolbar .md-toolbar-action i { font-size: 11px; }
.md-body .md-preview {
  flex: 1;
  padding: 12px 16px;
  font-size: 14px;
  line-height: 1.7;
  overflow-y: auto;
  border-left: 1px solid #e7e5e4;
  word-break: break-word;
  min-height: 320px;
}
.md-body .md-preview:empty::before {
  content: '（開始輸入後，預覽會出現在這裡）';
  color: #c4bfb8;
  font-style: italic;
  font-size: 13px;
}
.md-body .md-preview p:first-child { margin-top: 0; }
.md-body .md-preview p:last-child { margin-bottom: 0; }
.md-body .md-preview pre {
  background: #f6f8fa;
  padding: 10px 12px;
  border-radius: 6px;
  overflow-x: auto;
  font-size: 12px;
}
.md-body .md-preview code {
  font-size: 13px;
  background: #eef2f1;
  padding: 1px 5px;
  border-radius: 3px;
  font-family: 'JetBrains Mono', monospace;
}
.md-body .md-preview pre code { background: none; padding: 0; font-size: 12px; }
.md-body .md-preview a { color: var(--brand-dark, #028090); }

/* Blockquote styling — visually distinct from code (which has a solid gray
   bg) so a single-line `> quote` doesn't get confused with `` `code` ``.
   Applied to every preview surface we own: the live editor preview
   (.md-preview), the rendered profile bio (.profile-about), and the
   notes view/preview (.note-view / .sn-preview). The notes template loads
   profile.css so a single rule covers all four contexts.                  */
.profile-about blockquote,
.md-body .md-preview blockquote,
.note-view blockquote,
.sn-preview blockquote {
  margin: 8px 0;
  padding: 6px 14px;
  border-left: 3px solid var(--brand, #00A896);
  background: #f5fbfa;
  color: #57534e;
  border-radius: 0 6px 6px 0;
}
.profile-about blockquote > :first-child,
.md-body .md-preview blockquote > :first-child,
.note-view blockquote > :first-child,
.sn-preview blockquote > :first-child { margin-top: 0; }
.profile-about blockquote > :last-child,
.md-body .md-preview blockquote > :last-child,
.note-view blockquote > :last-child,
.sn-preview blockquote > :last-child { margin-bottom: 0; }

/* Mode toggles */
.md-body[data-mode="edit"]    textarea  { display: block; }
.md-body[data-mode="edit"]    .md-preview { display: none; }
.md-body[data-mode="split"]   textarea  { display: block; }
.md-body[data-mode="split"]   .md-preview { display: block; }
.md-body[data-mode="preview"] textarea  { display: none; }
.md-body[data-mode="preview"] .md-preview {
  display: block;
  border-left: none;
}

/* GFM tables in the preview pane (table button on the syntax toolbar
   inserts a 3×3 starter). Notes' view mode keeps its own .note-view
   table rules separately. */
.md-preview table {
  border-collapse: collapse;
  margin: 10px 0;
  font-size: 13px;
  background: #fff;
}
.md-preview th {
  background: #e6f5f2;
  color: #00A896;
  font-weight: 600;
  padding: 6px 10px;
  border: 1px solid #b8e0db;
  text-align: left;
}
.md-preview td {
  padding: 6px 10px;
  border: 1px solid #e8e8e8;
  background: #fff;
}
.md-preview tr:nth-child(even) td { background: #f7f7f7; }

/* Spoiler block (:::spoiler ... :::). renderRich rewrites the fence into
   <details class="md-spoiler"><summary>title</summary>body</details>. */
.md-spoiler {
  border: 1px solid #00A896;
  border-radius: 6px;
  padding: 6px 12px;
  margin: 10px 0;
  background: #f0faf8;
}
.md-spoiler > summary {
  cursor: pointer;
  font-weight: 600;
  color: #00A896;
  outline: none;
  user-select: none;
  padding: 2px 0;
  list-style: none;
}
.md-spoiler > summary::-webkit-details-marker { display: none; }
.md-spoiler > summary::before {
  content: '\25B6';
  display: inline-block;
  margin-right: 6px;
  font-size: 10px;
  transition: transform 0.15s;
}
.md-spoiler[open] > summary::before { transform: rotate(90deg); }
.md-spoiler[open] > summary {
  margin-bottom: 6px;
  border-bottom: 1px dashed #b8e0db;
}
.md-spoiler > *:not(summary) { margin-top: 0; }
.md-spoiler > *:last-child { margin-bottom: 0; }

/* Save button row sitting directly below the About-me editor */
.md-save-row {
  margin-top: 10px;
  display: flex;
  justify-content: flex-end;
}

/* Inline "saved / saving / error" indicator that appears next to an
   auto-saving field after the user changes it.                           */
.field-saved-ind {
  display: inline-block;
  margin-left: 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  opacity: 0;
  transition: opacity 0.2s ease;
}
.field-saved-ind.saving  { opacity: 1; color: #a8a29e; }
.field-saved-ind.saved   { opacity: 1; color: var(--brand-dark, #028090); animation: fade-out 1.6s 1.2s forwards; }
.field-saved-ind.error   { opacity: 1; color: #b91c1c; }
@keyframes fade-out { to { opacity: 0; } }

/* External-OJ "Profile URL: https://.../<your handle>" hint row that
   sits under the input on every unlocked OJ. The link is fully clickable
   and updates live as the user types. */
.settings-oj-url-preview {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 11px;
  color: #78716c;
  font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, monospace;
}
.settings-oj-url-preview i {
  color: var(--brand, #00A896);
  font-size: 10px;
}
.settings-oj-url-label {
  font-family: 'Noto Sans TC', sans-serif;
  font-size: 11px;
  color: #a8a29e;
  white-space: nowrap;
}
.settings-oj-url-preview a {
  color: var(--brand-dark, #028090);
  text-decoration: none;
  word-break: break-all;
}
.settings-oj-url-preview a:hover { text-decoration: underline; }
.settings-oj-url-handle {
  color: #c4bfb8;        /* placeholder when handle empty */
  font-style: italic;
}
.settings-oj-url-handle.is-filled {
  color: var(--brand, #00A896);
  font-weight: 700;
  font-style: normal;
}

/* === Phase 1c — Profile shared notes card =====================
   Lives in profile-main column, below Recent submissions
   (Anna 2026-05-15 reordered out of hero card). Anon viewers see
   the title list (discovery); clicking through to /notes/<id>/
   gates on login (per §2.1). Title uses .profile-card-title style
   (same as Recent submissions card), so no separate styling here.
*/
.profile-shared-notes-card .profile-card-title i.fas { color: var(--brand, #00A896); }
.profile-shared-notes-list {
    list-style: none;
    padding: 0;
    margin: 0 0 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.profile-shared-note-item {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
    align-items: baseline;
    line-height: 1.4;
}
.profile-shared-note-link {
    color: var(--brand-dark, #028090);
    text-decoration: none;
    font-weight: 600;
}
.profile-shared-note-link:hover { text-decoration: underline; }
.profile-shared-note-desc {
    color: #6a5232;
    font-size: 13px;
    flex: 1 1 100%;
    line-height: 1.5;
}
.profile-shared-note-meta {
    color: #a8a29e;
    font-size: 12px;
    margin-left: auto;
    white-space: nowrap;
}
.profile-shared-notes-more {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: var(--brand, #00A896);
    text-decoration: none;
    font-weight: 500;
}
.profile-shared-notes-more:hover { text-decoration: underline; }
.profile-shared-notes-more i.fas { font-size: 10px; }
