/* Built for small children playing together, so: big type, big targets, rounded
   everything, and colour used to tell things apart rather than to decorate.

   Still no framework and no JavaScript. The palette and shapes follow the animal fact
   cards in static/animals/, so opening one feels like part of the same game rather
   than a document from somewhere else.

   One light theme, deliberately. The fact cards are light-only -- a white card on a
   transparent page -- so a dark mode would leave half the game dark and the cards it
   opens bright. A children's game is better off bright and consistent than clever. */

:root {
    color-scheme: light;

    --ink: #23282e;           /* body text: near-black, easy on the eye */
    --ink-soft: #55606c;      /* secondary text, still comfortably readable */
    --paper: #fffdf7;         /* the page: warm white, not clinical */
    --card: #ffffff;
    --rule: #dfe6ee;

    --sky: #eaf4fc;           /* the three tints the fact cards use */
    --sky-edge: #bcdcf3;
    --leaf: #eaf7ec;
    --leaf-edge: #bfe4c6;
    --sun: #fdf3e3;
    --sun-edge: #f3d9a8;

    --go: #1c7a4b;            /* yes, play, teach -- the forward action */
    --go-dark: #14603a;
    --stop: #b23c1c;          /* no, and the undoing of things */
    --stop-dark: #8d2f16;
    --grape: #6a4bab;         /* the header band and headings */
    --error: #a3231a;

    --shadow: 0 6px 18px rgba(20, 30, 45, 0.10);
    --round: 20px;
    --round-small: 14px;

    /* Fingers, not mice: nothing tappable is smaller than this. */
    --tap: 3.25rem;
}

*, *::before, *::after {
    box-sizing: border-box;
}

body {
    font-family: "Comic Sans MS", "Chalkboard SE", "Trebuchet MS", system-ui, sans-serif;
    font-size: 1.125rem;
    line-height: 1.55;
    color: var(--ink);
    background: var(--paper);
    max-width: 34rem;
    margin: 0 auto;
    padding: 1rem 1rem 3rem;
    -webkit-text-size-adjust: 100%;
}

/* Non-production only. Deliberately the loudest thing on the page: its whole job is
   to stop someone mistaking a test site for the real one. */
.environment {
    margin: -1rem -1rem 1rem;
    padding: 0.45rem 1rem;
    background: var(--stop);
    color: #fff;
    text-align: center;
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

/* --- the header ---------------------------------------------------------- */

header {
    position: relative;                 /* the two icon buttons are placed against it */
    text-align: center;
    margin-bottom: 1.5rem;
}

h1 {
    margin: 0;
    /* Room at both ends for the two buttons, so the title stays centred between them
       rather than centred across the box and colliding with one. */
    padding: 0.6rem 5.6rem;
    background: var(--grape);
    color: #fff;
    border-radius: var(--round);
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    box-shadow: var(--shadow);
}

h1::after {
    content: " 🐾";
}

/* The two icon buttons beside the title: the settings, and the stars won. Both are
   placed against the header rather than laid out in a row with the title, because the
   settings panel has to stay inside its own <details> -- that is what closes it --
   while the cog that opens it belongs up here. The header's right padding is the gap
   they sit in, so neither ever overlaps the title's box. */
.icon-button {
    position: absolute;
    /* Centred on the title band: (band height - button) / 2. */
    top: 0.75rem;
    width: 2.75rem;
    height: 2.75rem;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--sky);
    border: 2px solid var(--sky-edge);
    color: var(--ink);
    font-size: 1.4rem;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    list-style: none;
    z-index: 1;
}

.icon-button:hover {
    background: var(--sky-edge);
}

.icon-button:focus-visible {
    outline: 3px solid var(--grape);
    outline-offset: 2px;
}

.settings-toggle {
    right: 3.6rem;
}

.settings-toggle::-webkit-details-marker {
    display: none;
}

/* Three lines, drawn rather than typed: a glyph would be at the mercy of the font,
   and this is decoration for a control the markup already names (aria-label), so a
   screen reader should hear "Settings" rather than a description of a shape. */
.settings-toggle::after {
    content: "";
    width: 1.25rem;
    height: 0.9rem;
    border-top: 3px solid currentColor;
    border-bottom: 3px solid currentColor;
    box-shadow: inset 0 0 0 3px transparent;
    background:
        linear-gradient(currentColor, currentColor) center / 100% 3px no-repeat;
}

.settings[open] .settings-toggle {
    background: var(--sky-edge);
}

/* Empty until there is something in it, then gold: the header itself says whether
   there is anything worth opening. */
.stars-link {
    right: 0.6rem;
    color: var(--ink-soft);
    font-size: 1.6rem;
}

.stars-link.has-stars {
    color: #b8861f;
}

/* The panel below them: three boxes, one column, all the same width, and that width
   is the title's. */
.settings-panel {
    padding-top: 0.6rem;
    width: 100%;
}

.control-with-action {
    width: 100%;
}

/* The header controls. <details> rather than a scripted expander: the page has no
   JavaScript, and the browser's own disclosure widget needs none. Closed, each is one
   line of status; open, it explains itself and offers the way to change it. */
.control {
    position: relative;                 /* the open/closed caret hangs off this */
    margin: 0.6rem 0 0;
    /* Full width, matching the title band above: three boxes and a heading, all one
       column with one edge. */
    width: 100%;
    text-align: left;
    font-size: 0.95rem;
    background: var(--sky);
    border: 2px solid var(--sky-edge);
    border-radius: var(--round-small);
    overflow: hidden;
}

/* Closed, a control is one line: its question, then the answer. Sign out and the
   caret sit at the right-hand end, which is why the line leaves room for them. */
.control summary {
    cursor: pointer;
    padding: 0.6rem 5.5rem 0.6rem 0.9rem;
    min-height: var(--tap);
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    list-style: none;
}

/* A control with something that must stay reachable while it is closed. The action
   is a sibling of the <details> -- inside the <summary> it would toggle the box as
   well as act, and inside the <details> it would vanish whenever the box was shut. */
.control-with-action {
    position: relative;
}

.summary-action {
    position: absolute;
    top: 0.55rem;
    right: 2.4rem;
    margin: 0;
    z-index: 1;
}

.control summary::-webkit-details-marker {
    display: none;
}

.control summary::after {
    content: "▾";
    position: absolute;
    right: 0.9rem;
    color: var(--ink-soft);
}

/* Everything the box says when open, indented to the same line as its summary. */
.control-body {
    padding: 0 0.9rem 0.9rem;
}

/* Rename and sign out, side by side under the player's own box. */
.control-actions {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

.control-actions form {
    margin: 0;
}

.control[open] summary::after {
    content: "▴";
}

.control .label {
    color: var(--ink-soft);
    font-size: 0.9rem;
}

.control .value {
    font-weight: 700;
}

/* "(3 so far!)" -- the count, beside the name of whoever's animals these are. */
.control .count {
    font-weight: 400;
    color: var(--ink-soft);
}

.control .describe {
    margin: 0 0 0.5rem;
    color: var(--ink-soft);
    font-size: 0.9rem;
}

.control form {
    margin: 0;
}

.control button {
    margin-top: 0.5rem;
}

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

.prompt {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.35;
    margin: 0 0 1.25rem;
    color: var(--grape);
}

.note {
    color: var(--ink-soft);
    font-size: 0.95rem;
}

.error {
    background: #fdeceb;
    border: 2px solid #f3bdb8;
    border-radius: var(--round-small);
    color: var(--error);
    font-weight: 700;
    padding: 0.75rem 1rem;
}

.error::before {
    content: "⚠️ ";
}

/* --- forms --------------------------------------------------------------- */

label {
    display: block;
    margin: 1.25rem 0 0.35rem;
    font-weight: 700;
}

label.inline {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0 1.25rem 0 0;
    min-height: var(--tap);
    font-weight: 400;
}

input[type="text"],
input[type="email"] {
    font: inherit;
    color: var(--ink);
    background: var(--card);
    border: 2px solid var(--sky-edge);
    border-radius: var(--round-small);
    padding: 0.7rem 0.85rem;
    width: 100%;
    max-width: 24rem;
    min-height: var(--tap);
}

input[type="text"]:focus-visible,
input[type="email"]:focus-visible {
    outline: 3px solid var(--grape);
    outline-offset: 1px;
}

/* Radio buttons a small finger can actually hit. */
input[type="radio"] {
    width: 1.4rem;
    height: 1.4rem;
    accent-color: var(--go);
}

fieldset {
    background: var(--sun);
    border: 2px solid var(--sun-edge);
    border-radius: var(--round-small);
    margin: 1.25rem 0 0;
    padding: 0.25rem 1rem 0.75rem;
}

legend {
    color: var(--ink);
    font-size: 0.95rem;
    font-weight: 700;
    padding: 0 0.4rem;
}

/* --- buttons ------------------------------------------------------------- */
/* Big, rounded and coloured, and they move when pressed, so a child can see that
   something happened even before the next page arrives. */

button {
    font: inherit;
    font-weight: 700;
    color: #fff;
    background: var(--go);
    border: none;
    border-bottom: 4px solid var(--go-dark);
    border-radius: var(--round-small);
    padding: 0.7rem 1.5rem;
    margin-top: 1.25rem;
    min-height: var(--tap);
    cursor: pointer;
}

button:hover {
    background: var(--go-dark);
}

button:active {
    transform: translateY(2px);
    border-bottom-width: 2px;
}

button:focus-visible {
    outline: 3px solid var(--grape);
    outline-offset: 2px;
}

/* Yes and No side by side. They are opposites, so they do not look alike -- but each
   still says which it is, because colour alone is never the whole message. */
.choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.choices button {
    flex: 1 1 8rem;
    margin-right: 0;
    min-width: 7rem;
    font-size: 1.15rem;
}

.choices button[value="no"],
.choices button[value="cancel"] {
    background: var(--stop);
    border-bottom-color: var(--stop-dark);
}

.choices button[value="no"]:hover,
.choices button[value="cancel"]:hover {
    background: var(--stop-dark);
}

/* The quiet ones: renaming yourself, stopping sharing. Not things to invite a child
   to press, so they stay out of the way. */
button.plain {
    background: transparent;
    color: var(--ink-soft);
    border: none;
    border-radius: var(--round-small);
    padding: 0.35rem 0.6rem;
    margin: 0;
    min-height: 2.5rem;
    font-size: 0.95rem;
    font-weight: 400;
    text-decoration: underline;
}

button.plain:hover {
    background: transparent;
    color: var(--ink);
}

button.danger {
    background: var(--stop);
    border-bottom-color: var(--stop-dark);
}

button.plain.danger {
    background: transparent;
    color: var(--stop);
}

a {
    color: var(--grape);
}

/* --- the list of whose animals to play with ------------------------------ */

.choices-list {
    list-style: none;
    padding: 0;
    margin: 1.5rem 0 0;
}

.choices-list li {
    background: var(--card);
    border: 2px solid var(--sky-edge);
    border-radius: var(--round-small);
    margin-bottom: 0.6rem;
    box-shadow: var(--shadow);
}

.choice {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    padding: 0.75rem 1rem;
    min-height: var(--tap);
    cursor: pointer;
}

.choice-name {
    font-size: 1.15rem;
    font-weight: 700;
}

/* --- animal tiles -------------------------------------------------------- */
/* A picture with the animal's name beneath it. The same tile is used to choose an
   animal and to remind the player which one they chose, so the two always look alike. */

.tiles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    margin: 1.5rem 0 0;
    justify-content: center;
}

.tile {
    /* Overrides the page's button rules: this one is a card, not a bar of text. */
    flex: 1 1 8.5rem;
    max-width: 12rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    padding: 0.75rem;
    border: 3px solid var(--sky-edge);
    border-bottom-width: 3px;
    border-radius: var(--round);
    background: var(--card);
    color: var(--ink);
    font: inherit;
    text-align: center;
    box-shadow: var(--shadow);
    min-height: 0;
}

/* Only the clickable ones invite a click. button.tile inherits the generic button
   rules, which would paint the whole card green -- so they are restated here. */
button.tile {
    cursor: pointer;
}

button.tile:hover,
button.tile:focus-visible {
    background: var(--card);
    color: var(--ink);
    border-color: var(--go);
}

button.tile:active {
    transform: translateY(2px);
}

/* Static tiles are pictures, not controls. The only thing to click on one is the
   badge in the corner, which has its own cursor. */
.tile-static {
    cursor: default;
}

/* A fixed box so tiles line up in a row whether the picture is tall, wide, or the
   "Animal Picture Missing" stand-in.

   Scoped to the direct child so it sizes the animal's photograph and not the notebook
   drawing inside the badge, which is also an <img> within a tile. */
.tile > img,
.tile-picture > img {
    display: block;
    width: 100%;
    height: 7rem;
    object-fit: contain;
    border-radius: var(--round-small);
}

/* Wraps the photograph so the badge has something its own size to sit in: a quarter
   of the picture, measured against the picture rather than against the whole tile. */
.tile-picture {
    position: relative;
    display: block;
    width: 100%;
}

/* "There is something to read about this one." Only drawn where a card exists, so its
   absence is as much a message as its presence -- and never on a tile that is itself a
   button, so there are never two targets a small finger has to choose between. */
.facts-badge {
    position: absolute;
    top: 0;
    right: 0;
    /* A quarter of the picture each way, but never smaller than a fingertip: a
       quarter of the small reminder pictures is about 18px, which no four-year-old
       can hit. */
    width: max(2.25rem, 25%);
    height: max(2.25rem, 25%);
    display: block;
    line-height: 0;
    border-radius: 50%;
}

.facts-badge > img {
    display: block;
    width: 100%;
    height: 100%;
}

.facts-badge:hover {
    transform: scale(1.08);
}

.facts-badge:focus-visible {
    outline: 3px solid var(--grape);
    outline-offset: 2px;
}

.tile-name {
    font-size: 1.2rem;
    font-weight: 700;
}

.tile-caption {
    color: var(--ink-soft);
    font-size: 0.85rem;
    text-transform: lowercase;
}

/* The reminder above a question: smaller, and clearly not the thing being asked. */
.reminder {
    margin: 0 0 1.5rem;
    justify-content: center;
}

.reminder .tile {
    flex: 0 1 8rem;
    padding: 0.5rem;
}

.reminder .tile > img,
.reminder .tile-picture > img {
    height: 4.5rem;
}

.reminder .tile-name {
    font-size: 1rem;
}

.other-animal {
    margin-top: 2rem;
    border-top: 2px dashed var(--rule);
    padding-top: 0.75rem;
}

/* Who wrote the question being asked. Deliberately quiet: it is a credit, not part of
   the question. */
.byline {
    margin: -0.75rem 0 1.5rem;
    color: var(--ink-soft);
    font-size: 0.9rem;
}

/* --- who else can play --------------------------------------------------- */

.friends {
    list-style: none;
    padding: 0;
    margin: 1.25rem 0 0;
}

.friends li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    background: var(--leaf);
    border: 2px solid var(--leaf-edge);
    border-radius: var(--round-small);
    margin-bottom: 0.6rem;
    padding: 0.6rem 0.9rem;
}

.friends form {
    margin: 0;
}

.friends button.plain {
    margin: 0;
}

.friend-email {
    word-break: break-word;
}

input[readonly] {
    color: var(--ink-soft);
    background: #f1f4f8;
    cursor: not-allowed;
}

/* --- the fact card ------------------------------------------------------- */
/* Shown only while the box is the document's :target, which is what lets a link open
   it with no JavaScript. */

.facts-popup {
    display: none;
}

.facts-popup:target {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 10;
}

/* The backdrop is a link covering the screen, so clicking anywhere outside the card
   clears the target and closes it -- the behaviour a dialog would need script for. */
.facts-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(20, 30, 45, 0.55);
}

/* Sized in dvh as well as vh. On a phone, 100vh is the window *without* the browser's
   own chrome subtracted, so a box measured in vh is taller than the screen actually
   shows and the bottom of the card is cut off -- which is why the three questions did
   not fit even closed. dvh is what is really visible; vh stays first as the fallback
   for anything that does not know dvh. */
.facts-box {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    width: calc(100% - 1rem);
    max-width: 34rem;
    height: 90vh;
    height: 90dvh;
    margin: 3vh auto;
    margin: 3dvh auto;
    padding: 0.5rem;
    background: var(--paper);
    border: 3px solid var(--sun-edge);
    border-radius: var(--round);
    box-shadow: var(--shadow);
}

/* min-height: 0 matters -- a flex item defaults to min-content, which for a frame of
   this card is taller than the space available, so the box grew past the screen
   instead of the frame fitting inside it. */
.facts-box iframe {
    flex: 1 1 auto;
    width: 100%;
    min-height: 0;
    border: 0;
}

.facts-close {
    align-self: center;
    flex: none;
    min-width: 9rem;
    padding: 0.55rem 1.5rem;
    background: var(--go);
    border-bottom: 4px solid var(--go-dark);
    border-radius: var(--round-small);
    color: #fff;
    font-weight: 700;
    text-align: center;
    text-decoration: none;
}

.facts-close:hover {
    background: var(--go-dark);
}

/* --- the duplicate-resolution screen ------------------------------------- */
/* One way of finding an animal: a card holding the route's questions and the button
   that declares it the best. Tinted in turn so the options are told apart at a glance
   as well as by their headings. */

.option-box {
    background: var(--sky);
    border: 3px solid var(--sky-edge);
    border-radius: var(--round);
    padding: 1rem 1.25rem;
    margin: 1.25rem 0;
    box-shadow: var(--shadow);
}

.option-box:nth-of-type(even) {
    background: var(--leaf);
    border-color: var(--leaf-edge);
}

.option-box:last-of-type {
    background: var(--sun);
    border-color: var(--sun-edge);
}

.option-box h2 {
    font-size: 1.15rem;
    font-weight: 700;
    margin: 0 0 0.5rem;
    color: var(--ink);
}

.option-box form {
    margin: 0.75rem 0 0;
}

.option-steps {
    margin: 0;
    padding-left: 1.35rem;
    color: var(--ink);
}

.option-steps li {
    margin-bottom: 0.25rem;
}

/* Motion is small and only on press, but it is still motion. */
@media (prefers-reduced-motion: reduce) {
    button:active,
    button.tile:active {
        transform: none;
    }
}

/* --- stars --------------------------------------------------------------- */

/* The congratulation after a star is won. Visible as soon as the page loads -- the
   player did something, and this is the answer to it -- and dismissed by targeting
   itself, which is the fact-card trick inverted: shown until :target, not after it.
   No JavaScript either way. */
.celebration {
    position: fixed;
    inset: 0;
    z-index: 20;
    display: grid;
    place-items: center;
    padding: 1rem;
    background: rgba(20, 30, 45, 0.55);
}

.celebration:target {
    display: none;
}

.celebration-box {
    width: 100%;
    max-width: 22rem;
    padding: 1.5rem;
    text-align: center;
    background: var(--paper);
    border: 3px solid var(--sun-edge);
    border-radius: var(--round);
    box-shadow: var(--shadow);
}

.celebration-lead {
    margin: 0;
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--grape);
}

.celebration-what {
    margin: 0.25rem 0 0.75rem;
    color: var(--ink);
}

.celebration-star {
    display: block;
    width: 7rem;
    height: 7rem;
    margin: 0 auto;
}

.celebration-name {
    margin: 0.5rem 0 0;
    font-size: 1.3rem;
    font-weight: 700;
}

.celebration-description {
    margin: 0.25rem 0 0;
    color: var(--ink-soft);
}

.celebration-close {
    display: inline-block;
    margin-top: 1.25rem;
    min-width: 9rem;
    min-height: var(--tap);
    padding: 0.7rem 1.5rem;
    background: var(--go);
    border-bottom: 4px solid var(--go-dark);
    border-radius: var(--round-small);
    color: #fff;
    font-weight: 700;
    text-decoration: none;
}

.celebration-close:hover {
    background: var(--go-dark);
}

/* The stars a player has won. The name is the label and the description is the
   flyover, so the list stays scannable and the story is one hover away. */
.star-list {
    list-style: none;
    padding: 0;
    margin: 1.5rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.star-list li {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.6rem 1rem;
    background: var(--sun);
    border: 2px solid var(--sun-edge);
    border-radius: var(--round-small);
}

.star-badge {
    flex: none;
    width: 3.5rem;
    height: 3.5rem;
}

.star-name {
    font-size: 1.2rem;
    font-weight: 700;
}

.return-link {
    margin-top: 2rem;
    text-align: center;
}

/* Narrow phones: the title band still has to hold two buttons and a word. */
@media (max-width: 24rem) {
    h1 {
        font-size: 1.6rem;
        padding: 0.6rem 5rem;
    }

    .icon-button {
        width: 2.5rem;
        height: 2.5rem;
        top: 0.6rem;
    }

    .settings-toggle {
        right: 3.1rem;
    }
}
