/* Student-facing web app: the home page plus shared chrome for the reading and
   writing surfaces. Deliberately quieter than the teaching console — a student
   opens this to do one piece of work, not to survey a class. */

.app-header {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 12px 26px;
  background: #1b2430;
  color: #fdfbf6;
}

.app-header .brand { color: #fdfbf6; text-decoration: none; font-weight: 700; display: flex; gap: 7px; align-items: center; }
.app-header .brand-mark { color: #d8c48a; }
.app-header .muted { color: #d8c48a; font-size: 13px; }

.back-link { color: #c9cfd6; text-decoration: none; font-size: 13px; }
.back-link:hover { color: #fdfbf6; }

.app-nav { display: flex; gap: 4px; margin-left: 12px; }

.app-tab {
  background: none;
  border: none;
  color: #c9cfd6;
  font: inherit;
  font-size: 14px;
  padding: 7px 13px;
  border-radius: 7px;
  cursor: pointer;
}

.app-tab:hover { background: rgba(255, 255, 255, 0.08); color: #fdfbf6; }
.app-tab.is-active { background: rgba(216, 196, 138, 0.18); color: #fdfbf6; }

.app-user { margin-left: auto; display: flex; align-items: center; gap: 12px; color: #c9cfd6; font-size: 13px; }

.app-main { max-width: 1000px; margin: 0 auto; padding: 30px 24px 90px; }
.app-main h1 { font-size: 1.5rem; margin: 0 0 4px; }

.section-heading { font-size: 0.95rem; margin: 28px 0 10px; color: #4b5563; font-weight: 600; }

.btn-sm { padding: 5px 11px; font-size: 13px; }
.small { font-size: 12px; }


.due-banner { display: flex; flex-direction: column; gap: 6px; margin: 14px 0 4px; }

.due-banner a {
  display: block;
  padding: 10px 14px;
  border-radius: 8px;
  background: #fdf3dc;
  border: 1px solid #e8d5a0;
  color: #1b2430;
  text-decoration: none;
  font-size: 14px;
}

.due-banner a:hover { background: #fbecc9; }

.assignment-grid,
.class-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}

.assignment-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 15px 16px;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.assignment-card:hover { border-color: #c9bf9d; transform: translateY(-1px); }
.assignment-card.is-overdue { border-left: 3px solid #b4453c; }
.assignment-card.is-soon { border-left: 3px solid #d8a53a; }

.ac-kind { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: #8a9199; }
.ac-title { font-weight: 600; font-size: 15px; }
.ac-class { font-size: 13px; color: #6b7280; }
.ac-doc { font-size: 12px; color: #8a9199; }

.ac-foot {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-top: 9px;
  font-size: 12px;
  flex-wrap: wrap;
}

.ac-status { font-weight: 500; }
.ac-done { color: #4a7c52; }
.ac-progress { color: #9a7b28; }
.ac-none { color: #8a9199; }
.ac-due { color: #6b7280; }
.ac-due-overdue { color: #b4453c; font-weight: 600; }
.ac-due-soon { color: #9a7b28; }

.class-card {
  padding: 15px 16px;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
}

.cc-name { font-weight: 600; }
.class-card button { margin-top: 8px; }

.past-details { margin: 18px 0 0; }
.past-details summary { cursor: pointer; color: #6b7280; font-size: 14px; padding: 6px 0; }
.past-details .assignment-grid { margin-top: 12px; }

/* ---- My words ---- */

.words-layout { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 26px; align-items: start; }

.words-toolbar { display: flex; gap: 10px; margin: 16px 0 14px; }
/* styles.css sizes form controls to full width for the console's stacked
   forms; this row is horizontal, so both need explicit basis. */
.words-toolbar input { flex: 1 1 auto; min-width: 0; }
.words-toolbar select { flex: 0 0 190px; width: 190px; }

.words-toolbar input,
.words-toolbar select {
  padding: 9px 12px;
  border: 1px solid #ddd7c8;
  border-radius: 8px;
  font: inherit;
  font-size: 14px;
}

.history-list { display: flex; flex-direction: column; gap: 8px; }

.history-item {
  padding: 12px 14px;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 9px;
}

.hi-main { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.hi-text { font-weight: 600; }
.hi-meaning { font-size: 13px; color: #4b5563; margin-top: 4px; }
.hi-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 7px; }

.star-btn {
  background: none;
  border: none;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  color: #b8bec5;
  padding: 2px 4px;
}

.star-btn:hover { color: #d8a53a; }
.star-btn.is-saved { color: #d8a53a; }
.star-btn:disabled { cursor: default; }

.ll-headword .star-btn { margin-left: 8px; vertical-align: middle; }

.saved-col { position: sticky; top: 18px; }
.saved-list { display: flex; flex-direction: column; gap: 7px; margin-top: 10px; }

.saved-item {
  position: relative;
  padding: 10px 34px 10px 12px;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 8px;
}

.si-text { font-weight: 600; font-size: 14px; }
.saved-item .star-btn { position: absolute; top: 8px; right: 8px; }

/* ---- Progress ---- */

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-top: 16px; }

.chart {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 110px;
  padding: 10px 12px;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 9px;
}

.chart .bar { flex: 1; background: #1b2430; border-radius: 2px; min-height: 2px; }

.chip-list { display: flex; flex-wrap: wrap; gap: 7px; }

.chip {
  padding: 5px 11px;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 999px;
  font-size: 13px;
}

@media (max-width: 860px) {
  .words-layout { grid-template-columns: 1fr; }
  .saved-col { position: static; }
  .app-header { flex-wrap: wrap; gap: 12px; }
  .app-user { width: 100%; margin-left: 0; }
}

.practice-link {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 15px 16px;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
  max-width: 520px;
}

.practice-link:hover { border-color: #c9bf9d; }
.practice-link span { font-size: 13px; }

/* Label above its control, sharing a left edge. The select used to carry
   margin-left: 8px from when the two sat on one line, so once they stacked the
   box was indented past its own label. */
.practice-lang {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  font-size: 13px;
  color: #6b7280;
  margin-bottom: 8px;
}

.practice-lang select {
  margin-left: 0;
  width: 100%;
  padding: 7px 10px;
  border: 1px solid #ddd7c8;
  border-radius: 7px;
  font: inherit;
  font-size: 13px;
  color: #1b2430;
  background: #fffdf8;
}

/* The shared .btn-ghost is built for the light page body; on the dark header it
   renders near-black on near-black. */
.app-header .btn-ghost {
  color: #c9cfd6;
  border-color: rgba(255, 255, 255, 0.22);
  background: transparent;
}

.app-header .btn-ghost:hover {
  color: #fdfbf6;
  border-color: rgba(255, 255, 255, 0.4);
  background: rgba(255, 255, 255, 0.08);
}

/* ---- Page heads ---- */

.page-head { margin-bottom: 22px; }
.page-head h1 { margin: 0 0 5px; }
.page-head p { margin: 0; max-width: 620px; line-height: 1.55; }

/* ---- Empty states ----
   An empty column that just says "nothing here" leaves a student wondering
   whether it's broken. These say what will fill it, and what to do meanwhile. */

.empty-state {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  text-align: center;
  padding: 34px 24px;
  background: #fff;
  border: 1px dashed #ddd7c8;
  border-radius: 12px;
}

.empty-icon {
  font-size: 20px;
  color: #c2a95f;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #fdf6e4;
  margin-bottom: 4px;
}

.empty-state strong { font-size: 15px; }
.empty-state .muted { font-size: 13px; max-width: 380px; line-height: 1.55; }

/* ---- Tiles ---- */

.tile-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }

.tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
  text-align: left;
  padding: 17px 18px;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 12px;
  text-decoration: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.tile:hover { border-color: #c9bf9d; transform: translateY(-1px); }
.tile strong { font-size: 15px; }
.tile .muted { font-size: 13px; line-height: 1.5; }

.tile-icon {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  background: #fdf6e4;
  color: #9a7b28;
  font-size: 14px;
  margin-bottom: 5px;
}

/* ---- Account ---- */

/* Two comfortable columns rather than three cramped ones. The account cards
   hold prose and long email addresses, neither of which survive a 300px box. */
.account-layout { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 16px; }

.account-layout .card {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.account-layout .card h3 { margin: 0 0 8px; font-size: 1rem; }
.account-layout .card p { line-height: 1.55; margin: 0 0 4px; }
.account-layout .card .btn { margin-top: auto; }
.account-layout .card .btn + .btn { margin-top: 8px; }

/* The shared .kv reserves a fixed 170px for labels, which inside a card leaves
   too little for an email address — it was being clipped. Stacked instead. */
.account-layout .kv {
  display: block;
  width: 100%;
  margin-bottom: 14px;
  font-size: 0.9rem;
}

.account-layout .kv dt {
  color: var(--muted);
  font-weight: 600;
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 10px;
}

.account-layout .kv dt:first-child { margin-top: 0; }

.account-layout .kv dd {
  margin: 2px 0 0;
  overflow-wrap: anywhere;
}

.inline-form { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; width: 100%; }

.inline-form input {
  flex: 1 1 150px;
  min-width: 0;
  padding: 9px 12px;
  border: 1px solid #ddd7c8;
  border-radius: 8px;
  font: inherit;
  font-size: 14px;
}

.inline-form .btn { margin-top: 0; }
.account-layout .inline-form + .error { margin-top: 10px; }

/* Installed is a resolved state, not a call to action. */
.is-ok { border-color: #cfe0d0; background: #fbfdfb; }

@media (max-width: 700px) {
  .account-layout { grid-template-columns: 1fr; }
  .app-nav { flex-wrap: wrap; }
}

/* The teaching card holds three routes and needs the full row. */
.wide-card { grid-column: 1 / -1; }

.route-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; width: 100%; margin-top: 6px; }
.route { display: flex; flex-direction: column; align-items: flex-start; }
.route strong { font-size: 14px; margin-bottom: 3px; }
.route p { margin: 0 0 6px; }
/* The form sits at the bottom of its column so the inputs and buttons line up
   across routes whose descriptions run to different lengths.
   The error is taken out of flow into a reserved strip beneath it. In flow it
   changed the column's height, which moved both its own form and — because the
   grid row grew — the form in the column beside it: showing "You already belong
   to an organization" under one route pushed the two columns 35px out of line
   with each other. Out of flow, an error appears without moving anything. */
.route { position: relative; padding-bottom: 20px; }
.route .inline-form { margin-top: auto; padding-top: 8px; }
.route .link-row { margin-top: auto; padding-top: 8px; }
.route > .error {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.3;
}

.switched-banner {
  padding: 12px 16px;
  border-radius: 10px;
  background: #eef5ee;
  border: 1px solid #cfe0d0;
  font-size: 14px;
  line-height: 1.55;
  margin-bottom: 18px;
}

/* The extension is the product, so this is a real prompt rather than a
   dismissible footnote — but it only shows when it isn't installed. */
.ext-prompt {
  display: flex;
  align-items: center;
  gap: 20px;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 16px 20px;
  border: 1px solid #e8d5a0;
  background: #fdf6e4;
  border-radius: 11px;
  margin-bottom: 20px;
}

.ext-prompt-body strong { display: block; font-size: 15px; margin-bottom: 3px; }
.ext-prompt-body p { margin: 0; font-size: 13px; line-height: 1.55; max-width: 55ch; }
.ext-prompt .btn { flex: none; }

.app-tab-link { text-decoration: none; display: inline-flex; align-items: center; }
.app-tab-link:hover { background: rgba(255, 255, 255, 0.08); color: #fdfbf6; }

/* The join button was sitting right against the last class card. */
#classList + .btn { margin-top: 16px; }

/* Equal columns, so the two boxes are the same width and their labels line up
   whether they sit side by side or wrap onto separate rows. */
.practice-controls { display: flex; gap: 18px; flex-wrap: wrap; margin-bottom: 16px; }
.practice-controls .practice-lang { flex: 1 1 240px; min-width: 0; margin-bottom: 0; }
.practice-controls select { min-width: 0; }

.faq-list { margin: 6px 0 10px; padding-left: 20px; font-size: 0.88rem; line-height: 1.65; color: #4b5563; }
.faq-list li { margin-bottom: 6px; }

/* Class detail. The cards inside reuse the assignment card from the main list,
   so a class opened from here looks like the work list it came from. */
#classDialog {
  max-width: 640px;
  width: calc(100vw - 48px);
  border: 1px solid var(--border);
  box-shadow: 0 18px 48px rgba(20, 17, 10, 0.18);
}
/* The shared .dialog-form is a fixed 380px, which left this one 380px of
   content floating inside a 640px dialog — which is why Close looked adrift
   rather than right-aligned. */
#classDialog .dialog-form { width: auto; padding: 24px 26px 20px; }
#classDialog h2 { margin: 0 0 4px; }
#classDialog > .dialog-form > .muted { margin: 0 0 4px; }

/* The actions sit on their own line, right-aligned, with a rule above — the
   Close button was floating under a card of variable width and looked adrift. */
#classDialog .dialog-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.class-dialog-heading {
  margin: 18px 0 8px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
}
.class-dialog-heading:first-child { margin-top: 12px; }

/* One per row inside the dialog. Two narrow columns made short lists look
   lopsided, and an assignment card reads better full width here. */
#classDialogBody .assignment-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}
#classDialogBody { max-height: min(58vh, 520px); overflow-y: auto; }
.class-card { cursor: pointer; }
.class-card:hover { border-color: var(--gold-border); }

/* Redundant inside the class dialog — the heading already names the class. */
#classDialogBody .ac-class { display: none; }

/* ---------- My readings ----------
   Your own PDFs. The drop target is a <label> wrapping a hidden file input, so
   clicking and keyboard activation come from the input rather than from script. */

.readings-intro { margin: -2px 0 12px; max-width: 60ch; }

.reading-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 22px 18px;
  border: 1.5px dashed #ded7c5;
  border-radius: 12px;
  background: #fffdf8;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.reading-drop:hover,
.reading-drop:focus-within { border-color: var(--gold-border); }
.reading-drop.is-over { border-color: var(--gold-border); background: #fdf6e6; }
.reading-drop.is-busy { cursor: progress; opacity: 0.7; }
.reading-drop-icon { font-size: 19px; color: #a6802d; line-height: 1; }
.reading-drop strong { font-size: 14px; }

.reading-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 10px;
  margin-top: 12px;
}

.reading-card {
  display: flex;
  align-items: stretch;
  background: #fff;
  border: 1px solid #e6e1d4;
  border-radius: 12px;
  overflow: hidden;
  transition: border-color 0.15s ease;
}

.reading-card:hover { border-color: var(--gold-border); }

.reading-open {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
  min-width: 0;
  padding: 14px 6px 14px 16px;
  text-decoration: none;
  color: inherit;
}

/* The filename is the only thing identifying it, so it wraps rather than
   truncating — three lines of title beats an ellipsis you can't read. */
.reading-open strong { font-size: 13.5px; overflow-wrap: anywhere; }
.reading-open .muted { font-size: 12px; }

.reading-scan {
  font-size: 11.5px;
  color: #9a6b1f;
}

.reading-delete {
  flex: none;
  width: 34px;
  border: none;
  border-left: 1px solid #f0ece0;
  background: none;
  color: #9c968a;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.reading-delete:hover { background: #fbf1f0; color: #b4453a; }

/* Plan card. Buttons wrap rather than shrink — a plan's price is part of its
   name, and truncating "Individual — $5 / month" loses the number. */
.billing-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 4px;
}

/* The access code card. Monospace and letter-spaced because a code is read off
   a screen and typed by hand, and XXXXX-XXXXX is easier to check that way. */
#accessCodeInput {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  min-width: 190px;
}

.ok-text { color: #2f6b45; font-size: 0.9rem; margin-top: 10px; }
#accessCodeMsg { margin-top: 10px; }
