/* Voice Journal surfaces (plan §3 A6a). Loaded alongside styles.css so the
   journal can ship its own layout without re-versioning the shared sheet.
   Primary controls keep the 44 px target the rest of the shell uses. */

.journal-view,
.journal-compose-view, .journal-profile-view {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 1.5rem;
}

/* The shell shows and hides every journal surface with the `hidden` attribute,
   and an author `display` beats the user agent's `[hidden]` rule - so each of
   these has to opt back in, the way `.menu-panel[hidden]` does in styles.css.
   Without this the three views stack on one page. */
.journal-view[hidden],
.journal-compose-view[hidden],
.journal-profile-view[hidden],
.journal-mode-choice[hidden],
.journal-composer[hidden],
.journal-preferences[hidden],
.journal-recorder[hidden],
.journal-confirmation-panel[hidden],
.journal-cards[hidden],
.journal-ladder[hidden],
.journal-profile[hidden],
.journal-consent-dialog:not([open]),
.menu-badge[hidden] {
  display: none;
}

/* Owner feedback 2026-09-01: a compact unread count beside the word
   "Journal", inline with the menu item's one line - never the readiness
   sentence, and never a second line that would shift the menu's layout. The
   full sentence lives only in the visually-hidden `#journal-badge-status`
   live region. */
.menu-badge {
  display: inline-block;
  min-width: 1.6rem;
  margin-inline-start: .4rem;
  padding: .1rem .45rem;
  border-radius: 999px;
  background: var(--accent, #c65d3b);
  color: white;
  font-size: .75rem;
  line-height: 1.4;
  white-space: nowrap;
  text-align: center;
}

/* Messaging preferences, inside the Settings "Messages" disclosure under the
   tick boxes, set apart from them by a rule rather than a second box. */
.journal-preferences {
  margin-top: 1rem;
  padding-top: .75rem;
  border-top: 1px solid rgb(0 0 0 / 12%);
}
.journal-preferences h3 { margin: 0 0 .75rem; }
.journal-preferences input, .journal-preferences select { min-height: 44px; }
/* styles.css makes every label `display: block`, which beats `[hidden]`: the
   custom-days label must opt back out or it shows under Daily and Weekly. */
.journal-preferences label[hidden] { display: none; }
.journal-preferences .capture-hint { margin: .25rem 0 .75rem; }
#journal-preferences-save { margin-top: .75rem; }

/* The new-thread page: the type-or-speak choice comes first, then the input. */
.journal-mode-choice { display: flex; flex-direction: column; gap: .75rem; }
.journal-mode-choice h2 { margin: 0; }
.journal-mode-choice-actions { display: flex; flex-wrap: wrap; gap: .65rem; }
.journal-mode-choice-actions button { flex: 1 1 12rem; min-height: 3.25rem; }

.journal-composer { display: flex; flex-direction: column; gap: .5rem; }
.journal-composer button { min-height: 3.25rem; }
#journal-mode-change { width: auto; min-height: 44px; padding: .5rem .9rem; align-self: flex-start; }
#journal-entry-text { min-height: 10rem; }

.journal-entry-list, .journal-corrections-list, .journal-keep-list, .journal-confirm-list {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.journal-entry-item {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  border: 1px solid rgb(0 0 0 / 12%);
  border-radius: .6rem;
  padding: .75rem;
}

.journal-entry-open { width: auto; min-height: 44px; padding: .5rem .8rem; text-align: start; }
.journal-entry-nav button { width: auto; min-height: 44px; padding: .5rem .8rem; }
.journal-entry-preview { margin: 0; opacity: .85; }


.journal-correction-item {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  border: 1px solid rgb(0 0 0 / 12%);
  border-radius: .6rem;
  padding: .75rem;
}

.journal-class-chip {
  align-self: start;
  border-radius: 999px;
  padding: .15rem .6rem;
  background: rgb(0 0 0 / 8%);
  font-size: .8rem;
  text-transform: capitalize;
}

.journal-original { text-decoration: line-through; }
.journal-suggested { font-weight: 600; }
.journal-rule, .journal-why, .journal-generalizes { margin: 0; font-size: .9rem; }


.journal-overall-note { margin: 0; font-style: italic; }

/* A6b: spoken capture, the consent gate and the confirmation panel. Every
   control below is a real button or input, at the same 44 px target. */

.journal-recorder { display: flex; flex-direction: column; gap: .5rem; }
.journal-recorder-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.journal-recorder-actions button { width: auto; min-height: 44px; padding: .6rem 1rem; }
#journal-record-review { width: 100%; min-height: 44px; }

.journal-consent-dialog {
  max-width: 34rem;
  border: 1px solid rgb(0 0 0 / 25%);
  border-radius: .6rem;
  padding: 1rem;
}
.journal-consent-copy { margin: 0 0 .75rem; }
.journal-consent { display: flex; align-items: start; gap: .5rem; min-height: 44px; }
.journal-consent input { min-width: 24px; min-height: 24px; }
.journal-consent-actions { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .75rem; }
.journal-consent-actions button { width: auto; min-height: 44px; padding: .6rem 1rem; }

.journal-confirmation-panel { display: flex; flex-direction: column; gap: .5rem; }
.journal-confirmation-list {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.journal-confirmation-item {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  border: 1px solid rgb(0 0 0 / 12%);
  border-radius: .6rem;
  padding: .75rem;
}
.journal-confirmation-question { margin: 0; font-weight: 600; }
.journal-confirmation-span {
  margin: 0;
  border-inline-start: 3px solid var(--accent, #c65d3b);
  padding: .25rem .7rem;
}
.journal-confirmation-alternatives { display: flex; flex-wrap: wrap; gap: .5rem; }
.journal-confirmation-alternative {
  width: auto;
  min-height: 44px;
  padding: .5rem 1rem;
  border-radius: 999px;
}
.journal-confirmation-fix { display: flex; flex-wrap: wrap; gap: .5rem; align-items: end; }
.journal-confirmation-fix input { min-height: 44px; flex: 1 1 12rem; }
.journal-confirmation-fix button, .journal-confirmation-skip {
  width: auto;
  min-height: 44px;
  padding: .5rem 1rem;
}
#journal-confirmation-finalize, #journal-corrections-answer {
  width: auto;
  min-height: 44px;
  padding: .6rem 1rem;
}
.journal-withheld { margin: 0; font-style: italic; }

/* The entry-screen opener (PRD VJ-CNV-009). Fixed copy chosen by the server
   from cadence, entry kind and whether anything is due; never generated, and
   never naming a plan. It hides itself before readiness has answered, so it
   opts back into `display: none` like every other hideable journal surface. */
/* v1.4 VJ-SUG: "Need an idea?" with three topics, shown only. */
.journal-topic-ideas {
  margin: 0 0 1rem;
}

.journal-topic-ideas[hidden] {
  display: none;
}

.journal-topic-ideas h2 {
  margin: 0 0 0.25rem;
  font-size: 1rem;
}

.journal-topic-ideas-list {
  margin: 0;
  padding-left: 1.25rem;
}

.journal-topic-ideas-list li {
  margin: 0.15rem 0;
}

/* B4: the entry's cards and the on-demand ladder. Both reuse the correction
   item's card shape and the same 44 px control target, so the corrections
   screen stays one visual language. */

.journal-cards-list, .journal-ladder-list {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.journal-card-item, .journal-ladder-item {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  border: 1px solid rgb(0 0 0 / 12%);
  border-radius: .6rem;
  padding: .75rem;
}

.journal-card-text, .journal-ladder-text { margin: 0; font-weight: 600; }
.journal-card-span, .journal-card-state,
.journal-ladder-lever, .journal-ladder-caution,
.journal-ladder-sentence { margin: 0; font-size: .9rem; }
.journal-ladder-caution { font-style: italic; }
.journal-ladder-action, .journal-card-action {
  width: auto;
  min-height: 44px;
  padding: .5rem .9rem;
  align-self: start;
}

/* B6 - the cross-session profile (PRD §6.8). Lists, not scores: nothing here
   is a number the learner is measured by (VJ-CNV-006). */
.journal-profile {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  margin: 1.5rem 0;
}

.journal-profile-level {
  margin: 0;
  font-size: 1.6rem;
  font-weight: 700;
}

.journal-profile h2 {
  margin: .75rem 0 0;
  font-size: 1.15rem;
}

/* The friend's note (owner's request, 2026-10-07): read like a message. */
.journal-profile-note {
  display: flex;
  flex-direction: column;
  gap: .6rem;
  max-width: 35rem;
  line-height: 1.55;
}

.journal-profile-note[hidden] {
  display: none;
}

.journal-profile-note p {
  margin: 0;
}

/* C0: self-service enablement (PRD VJ-CST-006, plan §4.5 T7). Lives inside the
   pair-setup ("Settings") view. Every toggle ships `disabled` in the markup
   and only a successful GET turns one on, so the copy is never ahead of what
   a click could actually do. */
#journal-settings {
  margin-top: 1.5rem;
  border: 1px solid rgb(0 0 0 / 12%);
  border-radius: .6rem;
  padding: .75rem 1rem;
}

#journal-settings[hidden] { display: none; }

/* Collapsed by default (no `open` attribute, and nothing here persists it).
   `<summary>` stays the first child so the h2 + pair-note travel with it as
   the disclosure's always-visible label - the only part of the box that
   still renders while closed. */
#journal-settings-summary {
  min-height: 44px;
  padding: .6rem 0;
  cursor: pointer;
}

#journal-settings-heading { margin: 0; }

/* Only populated for an unsupported pair (journal.js); `display: block`
   because a `<span>` is required here for `<summary>`'s content model, but
   it still needs to drop to its own line under the heading for the existing
   `.capture-hint` top margin to take effect. */
#journal-settings-pair-note { display: block; }

/* Locked shut for an unsupported pair (journal.js cancels the click/toggle
   that would otherwise open it): no pointer affordance, reads as inert. */
#journal-settings-summary[aria-disabled="true"] { cursor: default; }

.journal-settings-toggle {
  display: flex;
  align-items: center;
  gap: .75rem;
  min-height: 44px;
}

/* Exactly two flex children: the checkbox and one text span holding the
   whole sentence (pair name included). Without this, the raw text node and
   the `#journal-settings-language` span become separate flex items and wrap
   independently, splitting "Keep a journal in French" into its own columns
   with an empty gap between them. */
.journal-settings-toggle input {
  min-width: 24px;
  min-height: 24px;
  width: 24px;
  height: 24px;
  padding: 0;
  margin: 0;
  flex: 0 0 auto;
}

.journal-settings-toggle-text {
  flex: 1 1 auto;
  min-width: 0;
}

/* Message threads (PRD amendment v1.2, VJ-THR). The reply becomes the second
   message of a conversation, so it is laid out as one: the two roles are told
   apart by alignment and by the label above each message, never by colour
   alone. */
.journal-thread-messages {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .75rem;
}

.journal-thread-message {
  max-width: min(38rem, 88%);
  border-radius: .75rem;
  padding: .6rem .9rem;
  background: var(--surface-muted, #f2efe9);
}

.journal-thread-message-learner {
  align-self: flex-end;
  border-inline-end: 3px solid var(--accent, #c65d3b);
}

.journal-thread-message-friend {
  align-self: flex-start;
  border-inline-start: 3px solid var(--accent, #c65d3b);
}

.journal-thread-who {
  margin: 0 0 .2rem;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  opacity: .7;
}

.journal-thread-text {
  margin: 0;
  white-space: pre-wrap;
}

.journal-thread-form {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

/* Same 44 px target as every other journal control. */
.journal-thread-form button {
  min-height: 44px;
  align-self: flex-start;
}

/* Spoken thread replies (VJ-THR-002). */
.journal-thread-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

/* PRD amendment v1.4 (VJ-CVP-004): corrections on the conversation page. */
.journal-corrections {
  margin-top: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.journal-corrections > button {
  align-self: flex-start;
  min-height: 44px;
}

.journal-correction-place {
  margin: 0;
}

/* The two ways in lead the page, stacked above the conversations list:
   "Start a new message thread" in the accent colour, and "See what your friend
   knows about you" in green, so neither is mistaken for the other or for the
   outlined thread links below. A thread waiting on the learner says so on its
   own row (VJ-THR-001). */
.journal-compose-nav {
  display: flex;
  flex-direction: column;
  gap: .65rem;
  margin: .5rem 0 1rem;
}

.journal-compose-nav button {
  min-height: 44px;
}

.journal-profile-open {
  color: white;
  background: var(--success, #28654e);
}

.journal-profile-open:hover {
  background: var(--ink, #17332c);
}

.journal-entry-item-awaiting {
  border-inline-start: 3px solid var(--accent, #c65d3b);
  padding-inline-start: .6rem;
}

/* The friend wrote since the learner last looked (migration 0041). */
.journal-entry-item-new {
  border-inline-start: 3px solid var(--success, #28654e);
  padding-inline-start: .6rem;
}

.journal-entry-new {
  display: inline-block;
  margin-inline-start: .3rem;
  padding: 0 .45rem;
  border-radius: 999px;
  font-size: .8rem;
  font-weight: 700;
  color: white;
  background: var(--success, #28654e);
}

.journal-entry-reply {
  min-height: 44px;
  margin-top: .4rem;
}

/* A correction that failed is marked, not left looking unfinished. */
.journal-thread-correction-pending,
.journal-thread-correction-unavailable {
  opacity: .75;
}

.journal-thread-correction-unavailable {
  border-inline-start-style: dashed;
}

/* The friend is writing: three dots in the space the reply will take. With
   reduced motion they hold still; the visually-hidden words beside them are
   what a screen reader hears either way. */
.journal-typing-dots {
  display: flex;
  align-items: center;
  gap: .3rem;
  min-height: 1.5rem;
  margin: 0;
}

.journal-typing-dots span[aria-hidden="true"] {
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--muted, #60726c);
  animation: journal-typing 1.2s infinite ease-in-out;
}

.journal-typing-dots span[aria-hidden="true"]:nth-child(2) { animation-delay: .15s; }
.journal-typing-dots span[aria-hidden="true"]:nth-child(3) { animation-delay: .3s; }

@keyframes journal-typing {
  0%, 60%, 100% { opacity: .3; transform: translateY(0); }
  30% { opacity: 1; transform: translateY(-.2rem); }
}

@media (prefers-reduced-motion: reduce) {
  .journal-typing-dots span[aria-hidden="true"] { animation: none; opacity: .6; }
}

.journal-thread-form[hidden] { display: none; }

/* --------------------------------------------------------------------------
   Difficulty: Easy, Medium and Hard (PRD amendment v1.3, VJ-DIF).
   -------------------------------------------------------------------------- */

/* Each of these sets a `display`, so each opts back into `[hidden]` (see the
   note at the top of this file). `label` is `display: block` in styles.css. */
.journal-difficulty-fields[hidden],
.journal-difficulty-notice[hidden],
.journal-level-tag[hidden],
#journal-thread-input-field[hidden],
#journal-thread-type-instead[hidden] {
  display: none;
}

.journal-difficulty-fields {
  min-width: 0;
  margin: 1rem 0 .5rem;
  padding: .75rem 1rem;
  border: 1px solid var(--line, #d8d6ca);
  border-radius: .75rem;
}
.journal-difficulty-fields legend { padding: 0 .35rem; font-weight: 750; }

.journal-difficulty-option {
  display: flex;
  gap: .65rem;
  align-items: flex-start;
  margin: .5rem 0;
  font-weight: 500;
  line-height: 1.4;
}
/* A radio, not a text field: undo the full-width, 44 px input defaults. */
.journal-preferences .journal-difficulty-option input {
  width: auto;
  min-height: 0;
  margin-top: .2rem;
  flex: 0 0 auto;
}

/* A plain line naming the conversation's level. */
.journal-level-tag {
  margin: 0 0 .75rem;
  color: var(--muted, #60726c);
  font-size: .85rem;
  font-weight: 700;
}

/* Why Hard became Medium, or why a Hard message is shown as text
   (VJ-DIF-011). A note, not an error: nothing went wrong that the learner
   needs to fix right now. */
.journal-difficulty-notice {
  margin: 0 0 1rem;
  padding: .6rem .8rem;
  border-inline-start: 3px solid var(--accent, #c65d3b);
  border-radius: .5rem;
  background: var(--surface-muted, #f2efe9);
  line-height: 1.45;
}

/* Speaker icons, "Reveal" and "Play your recording" inside a message. */
.journal-thread-audio-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin-top: .5rem;
}
.journal-thread-audio-actions button {
  width: auto;
  min-height: 44px;
  padding: .45rem .8rem;
}
.journal-thread-audio-note { margin: .4rem 0 0; }

/* A Hard message's waveform (VJ-DIF-010): 48 bars scaled to the loudest,
   filled in as the message plays. */
.journal-waveform {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 2.75rem;
  margin: .3rem 0;
}
.journal-waveform span {
  flex: 1 1 0;
  min-width: 2px;
  border-radius: 2px;
  background: var(--muted, #60726c);
  opacity: .45;
}
.journal-waveform span.journal-waveform-played {
  background: var(--accent, #c65d3b);
  opacity: 1;
}
/* No peaks could be read: an even placeholder, visibly not a real shape. */
.journal-waveform-placeholder span { opacity: .25; }

#journal-thread-audio { width: 100%; margin: 0 0 1rem; }
#journal-thread-audio[hidden] { display: none; }

@media (prefers-reduced-motion: no-preference) {
  .journal-waveform span { transition: background-color .15s ease, opacity .15s ease; }
}

/* PRD amendment v1.4 (VJ-RVW): "Here is what we heard". */
.journal-review {
  margin: 1rem 0;
  padding: 0.75rem;
  border: 1px solid var(--line, #d0d7de);
  border-radius: 8px;
}

.journal-review[hidden],
.journal-review [hidden] {
  display: none;
}

.journal-review h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}

.journal-review-text {
  margin: 0.5rem 0;
  white-space: pre-wrap;
}

.journal-review-edit {
  display: block;
  margin: 0.5rem 0;
}

.journal-review-edit textarea {
  display: block;
  width: 100%;
  margin-top: 0.25rem;
}

.journal-review-actions,
.journal-review-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.journal-review-actions button,
.journal-review-choices button {
  min-height: 44px;
}


/* PRD amendment v1.4 (VJ-ADD-003): card suggestions, closed until opened. */
.journal-cards > summary {
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: .4rem;
  cursor: pointer;
  font-weight: 700;
  font-size: 1.1rem;
  list-style: none;
}

/* A flex summary loses the browser's disclosure triangle, which made the
   closed section read as an empty heading (owner's test, 2026-10-07). The
   chevron says it opens; the count says there is something inside. */
.journal-cards > summary::-webkit-details-marker {
  display: none;
}

.journal-cards > summary::before {
  content: "";
  width: .5rem;
  height: .5rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform .15s ease;
  flex: none;
}

.journal-cards[open] > summary::before {
  transform: rotate(45deg);
}

.journal-cards-count {
  font-weight: 400;
  color: var(--muted);
}

.journal-card-group h3 {
  margin: .8rem 0 .3rem;
  font-size: 1rem;
}

.journal-corrections-list .journal-card-state {
  margin: .3rem 0 0;
}
