/* Difficulty colors */

@property --novice-color {
    syntax: "<color>";
}

@property --adept-color {
    syntax: "<color>";
}

@property --master-color {
    syntax: "<color>";
}

@property --novice-bg {
    syntax: "<color>";
}

@property --adept-bg {
    syntax: "<color>";
}

@property --master-bg {
    syntax: "<color>";
}

/* These are re-set by Javascript, to ensure consistency. */
:root {
    --novice-color: black;
    --adept-color: black;
    --master-color: black;
    --novice-bg: white;
    --adept-bg: white;
    --master-bg: white;
}

.noviceColor {
    color: var(--novice-color);
    background-color: var(--novice-bg);
}

.adeptColor {
    color: var(--adept-color);
    background-color: var(--adept-bg);
}

.masterColor{
    color: var(--master-color);
    background-color: var(--master-bg);
}

/* Body */

body {
    display: flex;
    height: 100vh;
    margin: 0;
}

/* The two fundamental panes */

#paletteBar {
    background-color: #f0f0f0;
    padding: 10px;
    box-sizing: border-box;
    width: 100px;
    display: flex;
    flex-direction: column;
    /* Guarantee a gap between the scrolling palette and the buttons below it. */
    gap: 12px;
}

#palette {
    padding-top: 5px;
    flex: 1;
    overflow-y: auto;
}

#diagram {
    width: 100%;
    border-left: 1px solid #ccc;
    position: relative;
    /* A viewport onto the (effectively unbounded) #canvas; scroll to reach nodes placed far out. */
    overflow: auto;
}

#canvas {
    position: absolute;
    top: 0;
    left: 0;
    /* Fill the viewport by default; resizeCanvas() grows it past this to hold far-flung nodes. */
    min-width: 100%;
    min-height: 100%;
}

/* A box on the canvas is as wide as its contents: it must never re-wrap its text, which it
   otherwise would when dragged near the right-hand edge of the canvas, where the room an
   auto-width absolute box has to lay itself out in runs short. */
#canvas .rule {
    white-space: nowrap;
}

/* Ctrl/Cmd- or middle-dragging the background pans the canvas behind the viewport. */
#diagram.panready { cursor: grab; }
#diagram.panning, #diagram.panning * { cursor: grabbing; }

/* Basic rule styling */

.rule {
    height: 40px;
    color: black;
    line-height: 35px;
    margin-bottom: 10px;
    cursor: grab;
    padding: 0;
    z-index: 3;
    position: relative;
}

.basic {
    background-color: #dddddd;
    padding: 0px 8px 0px 8px;
    border-radius: 5px;
    border-style: solid;
    border-width: 1px;
}    

.logical {
    width: 42px;
}

.contextual {
    min-width: 42px;
}

.container {
    width: 58px;                /* 58 = 4 + 50 + 4 for the padding */
    background-color: rgba(255,255,255,0.0);
}

.intro {
    text-align: right;
}

.elim {
    text-align: left;
}

/* A bunch of classes for the sligthly kludgy pieces of binding rules */

.assumption {
    float: left;
    height: 100%;
    width: 22px;
    margin-left: 0px;
    border-style: solid;
    border-width: 1px;
    top: -2px;
    position: absolute;
    background-color: #dddddd;
}

.singleleft {
    border-radius: 5px 5px 0px 5px;
}

.doubleleft {
    border-radius: 5px;
}

.bar {
    width: 100%;
    height: 20px;
    border-style: solid;
    border-width: 1px;
    border-radius: 0px 0px 5px 5px;
    position: absolute;
    background-color: #dddddd;
}

.bottom {
    bottom: 0px;
    margin-bottom: 0px;
}

.mid {
    top: 50%;
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
}

.subgoal {
    float: right;
    height: 100%;
    width: 22px;
    margin-right: 0px;
    border-style: solid;
    border-width: 1px;
    top: -2px;
    right: -2px;
    position: absolute;
    background-color: #dddddd;
}

.singleright {
    border-radius: 5px 5px 5px 0px;
}

.doubleright {
    border-radius: 5px;
}

.subgoallabel {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    width: 100%;
}

.assumptionlabel {
    position: absolute;
    top: 20%;
    transform: translateY(-50%);
    text-align: center;
    width: 100%;
}

.bottomright {
    width: 4px;
    height: 20px;
    margin-bottom: 0px;
    position: absolute;
    bottom: 1px;
    right: 18px;
    background-color: #dddddd;
}

.bottomleft {
    width: 20px;
    height: 20px;
    margin-bottom: 0px;
    position: absolute;
    bottom: 1px;
    left: 10px;
    background-color: #dddddd;
}

.midright {
    width: 8px;
    height: 20px;
    position: absolute;
    right: 18px;
    background-color: #dddddd;
}

.midleft {
    width: 8px;
    height: 20px;
    position: absolute;
    left: 18px;
    background-color: #dddddd;
}

/* Dragging boxes from the palette */

.rule.dragging {
    opacity: 0.5;
}

/* Drag selection */

.jtk-drag-selected {
    outline-style: solid;
    outline-width: 5px;
    outline-color: #CCCC00;
}

.jtk-drag-select * {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

/* Group selection rectangle */

#selectionBox {
    position: absolute;
    border: 2px dashed #000;
    background: rgba(0, 0, 255, 0.1);
    pointer-events: none; /* so it doesn't block underlying elements */
    display: none;
}

/* Resizing bracket rules */

.resize-image {
    position: absolute;
    display: none;              /* Don't display in palette */
}

.resize-handle-right {
      width: 20px;
      height: 100%;
      position: absolute;
      right: 0;
      /* Added later by javascript, so it doesn't happen in the palette */
      /* cursor: ew-resize; */
}

.resize-handle-left {
      width: 20px;
      height: 100%;
      position: absolute;
      left: 0;
      /* Added later by javascript, so it doesn't happen in the palette */
      /* cursor: ew-resize; */
}

/* jsPlumb objects */

.jtk-connector {
    z-index: 4;
}

.jtk-endpoint {
    z-index: 3;
}

.jtk-overlay {
    z-index: 6;
}

/* The X button on each rule and connector */

.closebutton {
    background-color: red;
    color: white;
    border-radius: 50%;
    text-align: center;
    line-height: 20px;
    cursor: pointer;
    font-family: sans-serif;
    font-weight: bold;
    width: 20px;
    height: 20px;
    /* Hidden with visibility rather than display, so it is still laid out and can be measured:
       spreadWireLabels needs its size and position to keep the wire labels off it. */
    visibility: hidden;
}

.rule .closebutton {
    position: absolute;
    top: -10px;
    right: 5px;
}

.rule:hover .closebutton {
    visibility: visible;
}

/* Modal dialogs and their backgrounds that fade the rest of the page */

.modalbg {
    display: none;
    position: fixed;
    z-index: 100;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    justify-content: center;
    align-items: center;
}

/* A caution inside a modal dialog, e.g. what renaming a bound variable won't do for you. */
.dialog-warning {
    display: none;
    border-left: 4px solid #d08700;
    background-color: #fdf6e3;
    padding: 6px 10px;
    margin-top: 12px;
}
.dialog-warning.shown {
    display: block;
}
.modal {
    background-color: white;
    padding: 20px;
    border-radius: 10px;
    width: 500px;
    overflow-y: auto;
    max-height: 90%;
}

.hint {
    display: none;
}

/* Unicode insert buttons */

.unicode-button {
    background-color: #dddddd;
    position: relative;
    display: inline-block;
    margin: 2px;
    width: 16px;
    text-align: center;
    border-style: solid;
    border-width: 1px;
    cursor: pointer;
}

/* The grouped symbols at the end of a palette row, which share the buttons' look. */
.unicode-dropdown {
    background-color: #dddddd;
    position: relative;
    display: inline-block;
    margin: 2px;
    text-align: center;
    border-style: solid;
    border-width: 1px;
    cursor: pointer;
    font-family: inherit;
    font-size: inherit;
}

#shortcuts {
    margin-left: auto;
    margin-right: auto;
}

.symbol {
    text-align: center;
}

.keyseq {
    font-family: monospace;
    padding-left: 20px;
}

/* Level choices */

#worlds {
    flex: 1;
    min-height: 0;
    overflow-x: clip;
    overflow-y: auto;
    display: grid;
    /* Constrain the single column to the visible width (instead of growing to the widest content),
       so full-width custom-level rows don't overflow and clip their right-hand marks/delete. */
    grid-template-columns: minmax(0, 1fr);
    align-items: top;
}

/* The clickable index of worlds, pinned above the scrolling world list. */
#worldIndex {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    padding: 2px 0 4px;
    font-family: sans-serif;
}

.world-chip {
    padding: 4px 10px;
    border: 1px solid #888888;
    border-radius: 14px;
    background-color: #eeeeee;
    cursor: pointer;
    font-size: 14px;
    white-space: nowrap;
}

.world-chip.active {
    background-color: #333333;
    color: #ffffff;
    border-color: #333333;
}

/* The "done/total" level counts on the world chips. */
.world-progress {
    opacity: 0.65;
    font-size: 12px;
}

/* A world's name, which sticks to the top of the list while scrolling through that world. */
.world-header {
    position: sticky;
    top: 0;
    z-index: 5;
    background-color: #ffffff;
    text-align: center;
    font-size: 22px;
    font-weight: bold;
    font-family: sans-serif;
    padding: 8px 0;
    border-bottom: 2px solid #cccccc;
    margin-bottom: 6px;
}

.stage {
    width: 100%;
    display: grid;
    grid-template-columns: repeat(12, 70px);
    grid-auto-rows: 50px;
    gap: 10px;
    padding: 5px;
}

.stage-label {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3px;
    background-color: #ffffff;
    font-size: 18px;
    /* Name a font that contains all the logic/math symbols (∧ ∨ ⇒ ⇔ ¬ ⊤ ⊥ ∀ ∃ …) up front, so the
       whole label is shaped in one font.  Otherwise the browser falls back per-character and renders
       the double arrows ⇒/⇔ at different sizes depending on their neighbors. */
    font-family: "DejaVu Sans", "Noto Sans Symbols2", "Segoe UI Symbol", sans-serif;
}

.level {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    justify-content: center;
    gap: 1px;
    padding: 3px;
    /* so the hint bubble can sit in the corner */
    position: relative;
    background-color: #ffffff;
    font-size: 16px;
    font-family: sans-serif;
    border: 2px solid #000000;
    border-radius: 5px;
    cursor: pointer;
    overflow: hidden;
}

.level-number {
    font-size: 15px;
    font-weight: bold;
    line-height: 1.1;
}

.level-marks {
    display: flex;
    gap: 5px;
    align-items: center;
}

/* The two types written on a wire whose ends disagree about them, in the same red as the wire. */
.connLabel.mismatchLabel {
    color: #ff0000;
}
.lvmark {
    display: inline-flex;
    align-items: center;
    font-size: 17px;
    line-height: 1;
}

.lvmark .lockicon {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.2;
}

.lvmark.locked {
    opacity: 0.4;
}

/* A level whose easiest difficulty isn't unlocked yet: shown disabled. */
.level.level-locked {
    flex-direction: row;
    gap: 4px;
    background-color: #ededed;
    border-color: #aaaaaa;
    color: #999999;
    cursor: default;
}
/* In test mode a locked level keeps its three difficulty marks (each a completion toggle) instead
   of collapsing to one padlock beside the number, so it keeps the normal stacked layout too. */
.level.level-locked.level-toggles {
    flex-direction: column;
    gap: 1px;
    cursor: pointer;
}

/* A level that has a hint says so with an "i" filling its top-right corner: blue while the level
   is open, where clicking it shows the hint, and grey while the level is locked.  The level box
   clips its own rounded corner, so the square outer corner here comes out rounded to match. */

.hintbubble {
    position: absolute;
    top: 0;
    right: 0;
    width: 15px;
    height: 15px;
    border-bottom-left-radius: 8px;
    background-color: #0055cc;
    color: #ffffff;
    font-family: Georgia, "Times New Roman", serif;
    font-style: italic;
    font-weight: bold;
    font-size: 12px;
    line-height: 14px;
    cursor: pointer;
}

.hintbubble.locked {
    background-color: #aaaaaa;
    cursor: default;
}

/* An "active" level (has an unlocked, uncompleted difficulty): bright glow so the player can
   see at a glance where to work next. */
.level.level-active {
    box-shadow: 0 0 0 3px #ffb300, 0 0 9px 3px #ffd166;
}

.proofOption {
    font-size: 18px;
    white-space: normal;
    width: 65px;
    text-align: center;
}

#currentLevelAndDifficulty {
    position: absolute;
    top: 10px;
    right: 10px;
    font-family: sans-serif;
    text-align: right;
}

#currentLevel {
    text-align: center;
}

/* The difficulty label is tinted (in JS) with the current difficulty's color. */
#currentDifficulty {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 4px;
    border: 1px solid #00000033;
    font-weight: bold;
}

/* Non-modal "level complete" pop-up, pinned to the top center.  It is hidden until the level
   is complete, when JavaScript also tints it to match the current difficulty.  pointer-events
   are disabled on the bar itself (so it doesn't block dragging the proof) and re-enabled only
   on its buttons. */
#levelCompleteBanner {
    display: none;
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
    align-items: center;
    gap: 12px;
    padding: 8px 16px;
    border: 2px solid #000000;
    border-radius: 8px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    font-family: sans-serif;
    pointer-events: none;
}

#levelCompleteBanner.shown {
    display: flex;
}

#levelCompleteText {
    font-weight: bold;
}

#levelCompleteBanner button {
    font-size: 16px;
    pointer-events: auto;
}

/* The running block count on a level with a budget, in the same place at the top center as the
   "level complete" pop-up it gives way to, and with nothing to click.  Plain while the count is
   within budget; red once it is over. */
#blockCountBanner {
    display: none;
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
    padding: 8px 16px;
    border: 2px solid #000000;
    border-radius: 8px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    font-family: sans-serif;
    font-weight: bold;
    background-color: #ffffff;
    pointer-events: none;
}

#blockCountBanner.shown {
    display: block;
}

#blockCountBanner.over {
    color: #ffffff;
    background-color: #cc0000;
}

#reduceDifficulty, #showHint {
    display: none;
    text-align: center;
    margin-top: 5px;
    padding: 4px 10px;
    border: 1px solid #999999;
    border-radius: 5px;
    background-color: #f4f4f4;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    cursor: pointer;
    user-select: none;
}

#reduceDifficulty:hover, #showHint:hover {
    background-color: #e6e6e6;
}

#reduceDifficulty:active, #showHint:active {
    background-color: #d8d8d8;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
}

#levelChooseModal {
    max-height: 90%;
    position: relative;
    display: flex;
    flex-direction: column;
}

/* The "Custom" world lists saved player-made levels as full-width named rows (their names don't
   fit the tiny a-b-c boxes used for built-in levels). */
#customRows {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 6px 4px;
}

.custom-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 12px;
    border: 1px solid #000000;
    border-radius: 8px;
    background-color: #ffffff;
    cursor: pointer;
}

.custom-row:hover {
    background-color: #f0f0f0;
}

.custom-name {
    flex: 1;
    font-family: sans-serif;
    word-break: break-word;
}

.custom-marks {
    display: flex;
    gap: 3px;
    flex-shrink: 0;
}

.custom-delete {
    flex-shrink: 0;
    cursor: pointer;
    color: #aa3333;
    font-weight: bold;
    padding: 0 4px;
}

.custom-delete:hover {
    color: #ff0000;
}

.custom-empty {
    padding: 10px;
    color: #888888;
    font-family: sans-serif;
    font-size: 13px;
    text-align: center;
}

#customModal {
    max-height: 70%;
    position: relative;
    display: flex;
    flex-direction: column;
    width: 650px;
    /* Clip to the rounded corners; the inner #customScroll does the scrolling, so its scrollbar is
       inset within the modal's padding and the rounded right-hand corners stay visible. */
    overflow: hidden;
}

#customScroll {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
}

/* The title and the Submit/Back buttons live outside #customScroll so they stay visible while the
   body scrolls. */
#customModal > h3 {
    margin-top: 0;
}

/* Keep each bullet list tight against the paragraph that introduces it, and don't over-indent. */
#customScroll p {
    margin-bottom: 6px;
}

#customScroll ul {
    margin-top: 0;
    padding-left: 24px;
}

/* Without border-box the full-width fields overflow by their border, forcing a horizontal scrollbar. */
#customScroll textarea,
#customScroll input {
    box-sizing: border-box;
}

#ascribeModal {
    width: 650px;
    overflow: hidden;
}

#wireModal {
    width: 650px;
    overflow: hidden;
}

#chooseLevelButtons {
    margin-left: auto;
    margin-right: auto;
}

/* Difficulty choices */

.difficultyRadio {
    padding: 5px;
    margin: 5px;
    border-radius: 8px;
    border-style: solid;
    border-width: 2px;
    width: 100px;
    border-color: #000000;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* labels on connections */

.connLabel {
    background-color: #ffffff;
    padding: 5px;
    margin: 2px;
    /* A label sits at the middle of its wire, right where you'd aim to hover the wire itself, so
       it lets the pointer through to the wire underneath.  The user-entered ones are clickable,
       so they take it back. */
    pointer-events: none;
}

.connLabel.userLabel {
    pointer-events: auto;
}

.connLabelValue {
    color: #0000ff;
}

.userLabel {
    cursor: pointer;
}

/* The explanation of a wire's error, shown while the pointer is over that wire.  It never takes
   the pointer itself, so moving along the wire doesn't make it flicker. */

#wireTooltip {
    display: none;
    position: fixed;
    z-index: 100;
    max-width: 34em;
    padding: 8px 10px;
    background-color: #ffffff;
    border: 2px solid #ff0000;
    border-radius: 4px;
    white-space: pre-wrap;
    pointer-events: none;
    box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.3);
}

/* labels on endpoints */

.lowerInputLabel {
    position: absolute;
    right: 10px;
    color: #ff0000;
    white-space: nowrap;
}

.middleInputLabel {
    position: absolute;
    right: 10px;
    bottom: -10px;
    color: #ff0000;
    white-space: nowrap;
}

.upperInputLabel {
    position: absolute;
    right: 10px;
    bottom: 0px;
    color: #ff0000;
    white-space: nowrap;
}

.lowerOutputLabel {
    position: absolute;
    left: 10px;
    white-space: nowrap;
}

.upperOutputLabel {
    position: absolute;
    left: 10px;
    bottom: 0px;
    white-space: nowrap;
}

.middleOutputLabel {
    position: absolute;
    left: 10px;
    bottom: -10px;
    white-space: nowrap;
}

/* About text */

#aboutModal {
    max-width: 90%;
    width: 1000px;
    height: 80%;
    background-color: #cccccc;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
}

.about {
    font-size: 18px;
}
