body
{
    background-color: #cfcfcf;
}
a
{
    text-decoration: none;
}
img
{
    border: none;
}
input,textarea,select,button,.menuitem,.dropbtn,.langbtn
{
    border: 1px solid #000000;
    background-color: #f0f0f0;
    margin: 1px;
    color: #000000;
}
input:hover,textarea:hover,select:hover,button:hover,.menuitem:hover,.dropbtn:hover,.langbtn:hover
{
    background-color: #e0e0e0;
}
input[type=submit]:active,button:active,.menuitem:active,.dropbtn:active,.langbtn:active
{
    border: 1px solid #7f7f7f;
    color: #ffffff;
    background-color: #000000;
}
hr
{
    border-top: 1px solid #000000;
    border-bottom: 0px;
    height: 1px;
}
.menuitem,.dropbtn,.langbtn
{
    padding-right: 9px;
    padding-left: 9px;
    cursor: pointer;
}
.error,.red
{
    color: #cc0000;
}
.successmsg,.green
{
    color: #009900;
}
.fileinfo
{
    border: 1px solid #000000;
    padding: 3px;
    background-color: #ccffff;
    display: inline-block;
    overflow: hidden;
}
.fileinfo label
{
    font-weight: bold;
}
.slblmore
{
    color: #0000ff;
    cursor: pointer;
}
.hidden
{
    display: none;
}
input#more0:checked ~ div#fileselector0,input#more0:checked ~ label#lblmore1,input#more1:checked ~ div#fileselector1,input#more1:checked ~ label#lblmore2,input#more2:checked ~ div#fileselector2,input#more2:checked ~ label#lblmore3,input#more3:checked ~ div#fileselector3,input#more3:checked ~ label#lblmore4,input#more4:checked ~ div#fileselector4,input#more4:checked ~ label#lblmore5,input#more5:checked ~ div#fileselector5,input#more5:checked ~ label#lblmore6,input#more6:checked ~ div#fileselector6,input#more6:checked ~ label#lblmore7,input#more7:checked ~ div#fileselector7,input#more7:checked ~ label#lblmore8,input#more8:checked ~ div#fileselector8,input#more8:checked ~ label#lblmore9,input#more9:checked ~ div#fileselector9
{
    display: block;
}
input#more0:checked ~ label#lblmore0,input#more1:checked ~ label#lblmore1,input#more2:checked ~ label#lblmore2,input#more3:checked ~ label#lblmore3,input#more4:checked ~ label#lblmore4,input#more5:checked ~ label#lblmore5,input#more6:checked ~ label#lblmore6,input#more7:checked ~ label#lblmore7,input#more8:checked ~ label#lblmore8,input#more9:checked ~ label#lblmore9
{
    display: none;
}
.lang
{
    position: absolute; 
    display: inline-block;
    right: 9px;
}
.lang, x:-moz-any-link, x:default /* any FireFox */
{
    margin-top: -17px;
}
_::-moz-progress-bar, body:last-child .lang /* FireFox>=6 */
{
    margin-top: 0px;
}
.lang:not(*:root)  /* Chrome, Safari, Opera>=14, Adroid */
{
    margin-top: -17px;
}
.dropdown
{
    position: relative;
    display: inline-block;
}
.lang-content
{
    display: none;
    position: absolute;
    background-color: #f0f0f0;
    /* 180px, not 172: "Bahasa Indonesia" is the longest name in the menu and
       wrapped on browsers that round the em-based width down. Sized to the
       longest label rather than to the average one. */
    min-width: 180px;
    z-index: 1;
    border: #000000 solid 1px;
    right: 0;
}
.dropdown-content
{
    display: none;
    position: absolute;
    background-color: #f0f0f0;
    min-width: 148px;
    z-index: 1;
    border: #000000 solid 1px;
}
.dropdown-content a,.lang-content a
{
    color: #000000;
    padding: 3px 10px 3px 10px;
    text-decoration: none;
    display: block;
    border-bottom: #cccccc solid 1px;
}
.dropdown-content a:hover,.lang-content a:hover
{
    background-color: #000000;
    color: #ffffff;
}
.dropdown:hover .dropdown-content,.lang:hover .lang-content
{
    display: block;
}
.dropdown:hover .dropbtn,.lang:hover .langbtn
{
    background-color: #000000;
    color: #ffffff;
    border: #ffffff solid 1px;
}
.wzresponse
{
    word-wrap: break-word;
    background-color: #ffffff;
    border: #000000 solid 1px;
    width: 99%;
    padding: 5px;
    font-family: monospace;
    font-size: 1em;
}
.translateres
{
    word-wrap: normal;
    background-color: #ffffff;
    border: #000000 solid 1px;
    width: 972px;
    padding: 5px;
    font-family: sans-serif;
    font-size: 1.25em;
}
.clocktable
{ 
    background: #e6e6e6; 
    border-color: #767676;
    border-style: solid;
    border-width: 2px;
    empty-cells: show; 
    min-width: 700px;
}
.clockcaption 
{
    background: #767676;
    font-size: 23px;
    color: #ffffff;
    font-weight: bold;
    padding: 5px 0px;
}
.clockthead 
{
    background: #000000;
    color: #ffffff;
    border-left: 1px solid #000000;
    border-right: 1px solid #000000;
    border-top: 1px solid #000000;
    border-bottom: 1px solid #000000;
    padding: 4px 4px;
    text-align: left
}
.clocktfoot
{
    background: #767676;
    border-left: 1px solid #000000;
    border-right: 1px solid #000000;
    border-top: 1px solid #000000;
    border-bottom: 1px solid #000000;
    padding: 2px 4px;
    color: #ffffff;
    text-align: center
}
.clocktbody
{ 
    border: none;
}
.clocktd,.clocktr,.clockth
{
    border-top: none;
    border-left: none;
    border-right: none;
    border-bottom: none;
}
.clocktf
{
    border: #000000 solid 1px;
}
.qltreven 
{
    background: #a6a6a6;
}
.qltr 
{
    background: #c6c6c6;
}
.ipinfo
{
    border: #000000 solid 1px;
    border-collapse: collapse;
    empty-cells: show; 
    padding: 2px;
}
.ipinfo td
{
    border: #000000 solid 1px;
    font-family: sans-serif;
}
/* --- webfonts ------------------------------------------------------------ */
/* Only referenced by .charglyph-jp and .charsrow-jp below, so the browser
   fetches these on the kana and CJK pages and nowhere else. Together they are
   about 6.4MiB, which is a lot for a quiz: worth subsetting to the ranges
   actually used (kana plus the 214 radicals) with pyftsubset. Serve res/
   with a long Cache-Control, the files are immutable. */
@font-face
{
    font-family: 'Kiwi Maru';
    src: url('/res/KiwiMaru-Regular.woff2') format('woff2'),
         url('/res/KiwiMaru-Regular.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}
@font-face
{
    font-family: 'Zen Kaku Gothic New';
    src: url('/res/ZenKakuGothicNew-Regular.woff2') format('woff2'),
         url('/res/ZenKakuGothicNew-Regular.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}
/* --- character trainer --------------------------------------------------- */
.charsmenu
{
    line-height: 1.9em;
}
.charsmenu a,.charsmenuon
{
    border: 1px solid #000000;
    background-color: #f0f0f0;
    color: #000000;
    padding: 2px 6px;
    margin: 1px;
    white-space: nowrap;
}
.charsmenu a:hover
{
    background-color: #e0e0e0;
}
.charsmenuon
{
    background-color: #000000;
    color: #ffffff;
    border: 1px solid #7f7f7f;
}
.charscore
{
    border: 1px solid #000000;
    padding: 3px;
    background-color: #ccffff;
    overflow: hidden;
    /* A table box rather than an inline-block, so `margin: auto` centres it
       the same way .charstable and .charsanswers are centred. Both shrink to
       fit their content; only a table box can then be centred with auto
       margins, which an inline-block cannot.

       Deliberately NOT a row inside .charstable: that table is one column, so
       the column would widen to the feedback text and stretch the 150px grey
       glyph cell with it. Its own box keeps the two independent. */
    display: table;
    margin: 3px auto;
    text-align: center;
}
.score
{
    color: #aa00aa;
    font-weight: bold;
}
.pct
{
    color: #00aaaa;
    font-weight: bold;
}
.charstable
{
    border-collapse: collapse;
    /* auto margins on both tables centre each within the form, and therefore
       against each other -- the glyph sits over the middle of the answer
       grid whatever width that grid happens to be. Sizing one to the other
       is not possible here without a wrapper, and is not needed: they share
       a container, so centring both is enough. */
    margin: 9px auto;
}
.charsglyph
{
    background: #cccccc;
    border: #767676 solid 2px;
    width: 150px;
    height: 150px;
    text-align: center;
    vertical-align: middle;
}
.charglyph
{
    position: relative;
    z-index: 0;
    font-size: 5em;
    line-height: 1em;
    font-weight: bold;
    color: #000000;
}
/* --- weight of the Japanese glyph ---------------------------------------- */
/* The two webfonts ship a Regular face only -- the @font-face blocks above
   both declare font-weight: normal, so the family has nothing at 700. Asking
   for bold therefore cannot select a face; the browser fabricates one by
   smearing the outlines, and every engine smears by a different amount. That
   is why the same font looks heavier in some browsers than others, and why
   switching bold off fixes one browser while thinning the rest.

   font-synthesis: none stops the fabrication outright, so all engines draw
   the same Regular outlines. The stroke then adds weight back by a fixed,
   identical amount everywhere -- unlike synthesis, it is a number we control.

   Tune --jp-weight if it reads too light or too heavy; 0 gives plain Regular.
   The real fix is to ship an actual weight, see the note below, at which
   point set font-weight: 500 here and drop the stroke. */
.charglyph-jp
{
    --jp-weight: 0.022em;
    font-family: 'Kiwi Maru','Zen Kaku Gothic New',serif;
    font-weight: normal;
    font-synthesis: none;
    -webkit-text-stroke: var(--jp-weight) currentColor;
}
/* Shipping a real weight removes the need for the stroke entirely. Kiwi Maru
   has 300/400/500 (no 700); Zen Kaku Gothic New has 300/400/500/700/900.
   Fetch the Medium face, subset it the same way as the Regular, drop it in
   res/, then uncomment this and set font-weight: 500 above.

@font-face
{
    font-family: 'Kiwi Maru';
    src: url('/res/KiwiMaru-Medium.woff2') format('woff2'),
         url('/res/KiwiMaru-Medium.woff') format('woff');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
*/
.charsreading
{
    margin: 3px 0px;
    text-align: center;
}
.charsanswers
{
    border-collapse: separate;
    border-spacing: 1px;
    empty-cells: show;
    margin: 0px auto;
}
.charsanswer input,.charsnoidea input
{
    font-family: monospace;
    font-weight: bold;
    min-width: 4em;
    padding-left: 6px;
    padding-right: 6px;
}
.charsnoidea
{
    text-align: center;
    padding-top: 6px;
}
.charsnoidea input
{
    min-width: 12em;
}
.charsrow
{
    word-wrap: break-word;
    background-color: #ffffff;
    border: #000000 solid 1px;
    padding: 5px;
    font-size: 1.5em;
    line-height: 1.6em;
}
.charsrow-jp
{
    font-family: 'Zen Kaku Gothic New','Kiwi Maru',sans-serif;
    font-synthesis: none;
}
/* --- flag codes ---------------------------------------------------------- */
.flagfilter
{
    margin: 6px 0px;
}
.flagfilteron
{
    text-decoration: underline;
}
.flags .clocktd
{
    font-family: monospace;
    padding: 1px 6px;
    white-space: nowrap;
}
/* --- password leak lookup ------------------------------------------------ */
.passform
{
    margin: 6px 0px;
}
.passdigests table
{
    border: #000000 solid 1px;
    border-collapse: collapse;
    empty-cells: show;
    padding: 2px;
}
.passdigests td
{
    border: #000000 solid 1px;
    font-family: sans-serif;
    padding: 1px 6px;
}
.passdigests code
{
    font-family: monospace;
    word-wrap: break-word;
}
/* --- japanese vocabulary trainer ----------------------------------------- */
/* The reading and the answer buttons start blacked out and reveal on hover,
   so a word can be studied before its answer is visible. The checkbox is an
   off-screen toggle that reveals everything at once; it carries no state and
   needs no script. */
.japanglyph
{
    height: 190px;
    min-width: 150px;
    width: auto;
    padding: 6px 12px;
}
/* --- word orientation ---------------------------------------------------- */
/* Short words are set top to bottom, the way Japanese often is. Longer ones
   would need a second column to fit, which reads down-then-back-up-and-across
   and is worse than plain horizontal, so they switch. nowrap on both means a
   word can never break into a second line or column. The handler picks the
   class from the character count. */
.charword-vert
{
    display: inline-block;
    writing-mode: vertical-rl;
    text-orientation: upright;
    white-space: nowrap;
    font-size: 3.4em;
    line-height: 1.05em;
}
.charword-horiz
{
    display: inline-block;
    writing-mode: horizontal-tb;
    white-space: nowrap;
    font-size: 2.6em;
    line-height: 1.1em;
}
.charword-xl
{
    font-size: 5em;
}
.charword-sm
{
    font-size: 1.7em;
}
.reading
{
    /* position and z-index are load-bearing: the glyph below is set at
       several em with a tight line-height, so its line box overlaps upward
       into the reading. Without an explicit stacking order the glyph wins and
       swallows the pointer, leaving only the blank strip above the text
       hoverable. */
    position: relative;
    z-index: 2;
    display: inline-block;
    font-family: 'Zen Kaku Gothic New','Kiwi Maru',monospace;
    font-synthesis: none;
    font-size: 1em;
    background: #000000;
    color: transparent;
    cursor: help;
    user-select: none;
    padding: 0px 16px;
}
/* The transition lives on the revealed state, never on the hidden one.
   With it on the base rule, any restyle that resolves from unstyled to
   hidden ANIMATES THE MASK IN -- 0.25s of delay plus 0.2s of fade, during
   which the text is plainly readable. A spoiler that fades in is not a
   spoiler. Declared here instead, the mask is always applied instantly and
   only the reveal animates; un-hovering snaps back at once, which is the
   right behaviour for hiding something anyway. */
.reading:hover,.reading:focus
{
    background: #e8e8e8;
    color: #000000;
    transition: background 0.3s ease 0.2s, color 0.2s ease 0.25s;
}
.responses
{
    background-color: #000000;
    color: transparent;
    cursor: help;
}
.responses:hover,.responses:focus
{
    background-color: #cacaca;
    color: #000000;
    transition: background-color 0.3s ease 0.2s, color 0.2s ease 0.25s;
}
.checker
{
    display: none;
}
#expand-toggle:checked ~ * .responses,#expand-toggle:checked ~ * .reading
{
    background-color: #cacaca;
    color: #000000;
    cursor: auto;
    transition: background-color 0.3s ease 0.2s, color 0.2s ease 0.25s;
}
.expand-btn
{
    color: #0000ff;
    text-decoration: underline;
    cursor: pointer;
}
#expand-toggle:checked ~ * .expand-btn
{
    background-color: #000000;
    color: #ffffff;
}
/* --- accounts ------------------------------------------------------------ */
.authtable
{
    border-collapse: collapse;
    margin: 6px 0px;
}
.authtable td
{
    padding: 2px 6px;
}
/* A visible enclosure round each form. Only used where a page carries more
   than one -- the members area -- so the forms read as separate things
   rather than one long column of fields. */
.authbox
{
    border: 1px dotted #000;
}
/* Padding goes on the CELLS, not on the table. .authtable sets
   border-collapse: collapse, and in the collapsing border model a table's
   own padding is ignored (CSS 2.1 17.6.2) -- so "padding" on .authbox would
   have done nothing and left the text flush against the dotted line.
   
   Written as .authtable.authbox so it outranks the .authtable td above by
   specificity rather than by being further down the file. Equal specificity
   would mean this rule wins only while it stays below, which is not
   something the next person editing this file should have to know. */
.authtable.authbox td
{
    padding: 4px 8px;
}
.authlabel
{
    text-align: right;
    white-space: nowrap;
}
.authhead
{
    font-weight: bold;
    padding-top: 9px;
}
.authhint
{
    font-size: 0.85em;
    color: #555555;
}
.authsubmit
{
    padding-top: 6px;
}
.authform
{
    display: inline-block;
    vertical-align: top;
}
.wip
{
    border: 1px solid #000000;
    padding: 3px;
    background-color: #ffffcc;
    display: table;
}
.authhint a
{
    text-decoration: underline;
}
.menuform
{
    display: inline-block;
    margin: 0px;
}
.erasebtn
{
    color: #cc0000;
    font-weight: bold;
}
/* --- file listing -------------------------------------------------------- */
.filegrid
{
    display: flex;
    flex-wrap: wrap;
    gap: 9px;
}
.fileitem
{
    border: 1px solid #000000;
    background-color: #e6e6e6;
    padding: 5px;
    width: 210px;
    text-align: center;
    /* Positioning context for .filesel, the selection checkbox, which sits
       over the top-left corner of the thumbnail. */
    position: relative;
}
.filethumb
{
    max-width: 200px;
    max-height: 200px;
    /* So the tag overlay can sit on the picture: an inline image leaves a
       few pixels of descender below it, and the overlay would float over
       that gap rather than over the thumbnail. */
    display: block;
}
.filelabel
{
    word-wrap: break-word;
    overflow-wrap: anywhere;
    font-size: 0.85em;
    padding: 2px 0px;
}
/* <details> keeps the info box scriptless: the browser does the toggling. */
.fileinfobox
{
    text-align: center;
    margin: 0px;
}
/* Info, OTL and Delete on one line.
   <details> is ONE item in this row and keeps its own structure: a <summary>
   only acts as the disclosure control when it is a direct child, so it must
   not be wrapped. The panel it opens escapes the row by being positioned
   absolutely, which is what lets it use the full tile width instead of the
   third of it a flex item would get. */
.filebuttons
{
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 3px;
}
.filebuttons .authform
{
    display: inline-block;
    margin: 0px;
}
/* Info is a <summary>, OTL and Delete are <input type="submit">. An input
   does not inherit the document font and a summary does, so left alone the
   two have different line heights and Info stands a couple of pixels taller.
   Matching font, line-height, padding and border makes the three boxes
   identical. */
.filebuttons .submit,
.filebuttons .menuitem
{
    font-family: inherit;
    font-size: 1em;
    line-height: 1.2;
    margin: 0px;
    padding: 2px 8px;
    border: 1px solid #000000;
    box-sizing: border-box;
    white-space: nowrap;
}
.fileinfobox summary::-webkit-details-marker
{
    display: none;
}
/* Closed it is one button wide; open it claims the whole row so the panel
   lands beneath the buttons rather than beside them. */
.fileinfobox[open]
{
    flex-basis: 100%;
}
.fileinfobox summary
{
    /* list-style: none removes the disclosure triangle in Firefox; the
       -webkit rule above does it in Blink and WebKit. Without both, Info
       sits a few pixels lower than OTL and Delete. */
    list-style: none;
    cursor: pointer;
    border: 1px solid #000000;
    background-color: #f0f0f0;
}
.fileinfobox summary:hover
{
    background-color: #e0e0e0;
}
/* In the flow, deliberately. Absolute positioning made the open panel float
   over the tiles below it and cover their buttons; keeping it in the flow
   makes the tile grow instead, so several panels can be open at once and
   nothing is hidden behind anything.
   flex-basis: 100% puts it on its own line under the three buttons rather
   than beside them. */
.fileinfobox .fileinfo
{
    flex-basis: 100%;
    text-align: left;
    margin-top: 3px;
    padding: 3px;
    border: 1px solid #000000;
    background-color: #ccffff;
    font-size: 0.85em;
    word-wrap: break-word;
    overflow-wrap: anywhere;
}
.filespager,.filescount
{
    margin: 9px 0px;
}
.pageon
{
    border: 1px solid #7f7f7f;
    background-color: #000000;
    color: #ffffff;
    padding: 2px 9px;
}

/* --- delete confirmation ------------------------------------------------- */
/* Thumbnail, info box and buttons are three different widths stacked in one
   column. Auto margins centre each within the container and therefore against
   each other, so the buttons sit under the middle of the info box whatever
   width its longest line takes.

   auto margins only move a block-level box, and .fileinfo and .authform are
   both inline-block elsewhere; display: table shrink-wraps like inline-block
   while still accepting them. Scoped to .delconfirm so the same classes keep
   their existing behaviour on the upload page and in the grid.

   The scope is .delconfirm rather than .delfile because both confirmation
   pages use it: the share/paste one was missing the class entirely and so
   rendered left-aligned with its buttons beside the info box. One class for
   one layout beats two copies that can drift apart. */
.delconfirm .fileitem,
.delconfirm .fileinfo,
.delconfirm .authform
{
    display: table;
    margin-left: auto;
    margin-right: auto;
}
/* The thumbnail card sat flush against the info box below it. */
.delconfirm .fileitem
{
    margin-bottom: 12px;
}
/* The form is its own table box, so the buttons already start a new line;
   this is the gap above them. */
.delconfirm .authform p
{
    margin: 12px 0px 0px 0px;
    text-align: center;
}
/* --- link / paste listing ------------------------------------------------ */
.linkpastelist
{
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.linkpasteitem
{
    border: 1px solid #000000;
    background-color: #e6e6e6;
    padding: 6px 9px;
}
.linkpastelink
{
    font-family: monospace;
    font-weight: bold;
}
.linkpastebadge
{
    font-family: sans-serif;
    font-weight: normal;
    font-size: 0.8em;
    border: 1px solid #7f7f7f;
    padding: 0px 4px;
    margin-left: 4px;
}
.linkpastesummary
{
    word-wrap: break-word;
    overflow-wrap: anywhere;
    margin: 2px 0px;
}
.linkpastemeta
{
    font-size: 0.85em;
    color: #555555;
    margin-bottom: 3px;
}

/* --- members: account actions -------------------------------------------- */
/* Logout and Cancel account belong below the password table, not beside it.
   The forms are inline-block so they sit side by side with each other, but
   the wrapper is a block, which puts the pair on its own line. */
.accountactions
{
    margin-top: 18px;
}
/* --- registration captcha ------------------------------------------------ */
.captchaimg
{
    border: 1px solid #000000;
    background-color: #ffffff;
    vertical-align: middle;
    margin-bottom: 3px;
}
/* --- clipboard paste (progressive enhancement) --------------------------- */
/* The hint carries the `hidden` attribute in the markup and is only revealed
   by res/paste.js once it has confirmed the browser can do it. Without
   JavaScript it stays hidden and the page is unchanged. */
.pastehint
{
    font-size: 0.85em;
    color: #555555;
}
.pasteok
{
    color: #009900;
}
.pasteerr
{
    color: #cc0000;
}
/* Drag feedback. The class is added by res/paste.js only while a drag that
   actually carries files is over the form, so without JavaScript it never
   appears and the zone is an ordinary div. */
.upload.dragover
{
    outline: 2px dashed #009900;
    outline-offset: 4px;
    background-color: #f0fff0;
}
.otllink
{
    word-wrap: break-word;
    overflow-wrap: anywhere;
}
/* Clear button beside a filled file input. Added by res/paste.js only, and
   hidden until the input actually holds a file -- so without JavaScript, or
   with an empty slot, nothing appears. */
.clearfile
{
    border: 1px solid #000000;
    background-color: #f0f0f0;
    color: #cc0000;
    font-weight: bold;
    cursor: pointer;
    margin-left: 3px;
    padding: 0px 6px;
}
.clearfile:hover
{
    background-color: #e0e0e0;
}
.modowner
{
    font-size: 0.8em;
    color: #555555;
    padding-bottom: 2px;
}
.report textarea
{
    font-family: inherit;
    width: 100%;
    max-width: 32em;
}
/* --- moderation report queue --------------------------------------------- */
.reportlist
{
    margin: 9px 0px;
}
.reportitem
{
    border: 1px solid #000000;
    background-color: #e6e6e6;
    padding: 6px;
    margin-bottom: 9px;
}
/* A handled report stays readable but recedes, so the open ones stand out. */
.reporthandled
{
    background-color: #f4f4f4;
    color: #666666;
}
.reportwhy
{
    background-color: #ffffff;
    border: 1px solid #cccccc;
    padding: 3px;
    margin: 3px 0px;
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow-wrap: anywhere;
}
/* The moderation pages all link to each other; the members page links in.
   One line, wrapping rather than overflowing on a narrow window. */
.modnav
{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 3px;
    margin: 9px 0px;
}
/* --- API documentation ---------------------------------------------------- */
.apiex
{
    background-color: #ffffff;
    border: 1px solid #cccccc;
    padding: 6px;
    margin: 3px 0px 9px 0px;
    overflow-x: auto;
    white-space: pre;
}
.apitable
{
    border-collapse: collapse;
    margin-bottom: 9px;
}
.apitable th,
.apitable td
{
    border: 1px solid #cccccc;
    padding: 2px 6px;
    text-align: left;
    vertical-align: top;
}
.apitable th
{
    background-color: #e6e6e6;
}
/* The API key, shown once after generation and never again. */
.apikeyshown
{
    background-color: #ffffcc;
    border: 1px solid #000000;
    padding: 6px;
    word-wrap: break-word;
    overflow-wrap: anywhere;
}
/* The report an RSS link pointed at. The fragment scrolls to it; this is
   what makes it visible once you are there. */
.reportpicked
{
    outline: 2px solid #cc0000;
    outline-offset: 2px;
}
/* --- galleries and bulk selection ----------------------------------------- */
/* The action bar sits between the count line and the grid. */
.bulkbar
{
    margin: 6px 0px 9px 0px;
    padding: 6px;
    border: 1px dotted #000000;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}
/* Top-left of the tile, over the thumbnail. The tile is the positioning
   context: position: relative is set on the original .fileitem rule above,
   not repeated here -- a second .fileitem block would be a duplicate
   selector, which is the fault t_style.pl exists to catch. */
.filesel
{
    position: absolute;
    top: 4px;
    left: 4px;
    z-index: 2;
    width: 18px;
    height: 18px;
    margin: 0px;
}
/* A gallery tile is the same size as a file tile so the grid stays regular,
   but carries a name and a count instead of a thumbnail. */
/* .filegrid is a flex row, so align-items defaults to stretch and every tile
   is as tall as the tallest -- a file tile with a thumbnail. The gallery tile
   is therefore much taller than its content.
   
   Made a column flex container itself so the name/count block can take the
   slack and the button row still sits inside, at the bottom, where it does on
   a file tile. */
/* A gallery tile is a file tile with a folder on it.
   
   It used to override the background to #f0f0f0, which is what made
   galleries read as a different KIND of thing sitting among the files
   rather than as another item in the same grid. .fileitem already supplies
   the border, the padding, the width and the centring; only the column
   layout is added here, so the delete button can be pushed to the bottom.
   
   What distinguishes a gallery now is the icon, which is the same way a
   PDF is distinguished from a zip. */
.galleryitem
{
    display: flex;
    flex-direction: column;
}
/* flex: 1 rather than height: 100%. A percentage height against a stretched
   flex item resolved to the full tile, so the link covered the whole box and
   pushed the buttons out below it -- underneath the next row of tiles. */
.gallerylink
{
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-decoration: none;
    padding: 6px;
    text-align: center;
}
/* Sits at the bottom of the tile, inside it, like the file tile's row. */
.galleryitem .filebuttons
{
    margin-top: auto;
}
/* The name is bold where a file's label is not: within a tile that is now
   shaped like every other, this is the one thing saying "this holds
   things". */
.galleryname
{
    font-weight: bold;
    word-wrap: break-word;
    overflow-wrap: anywhere;
}
.gallerycount
{
    font-size: 0.85em;
}
/* The note beside the gallery field. Muted so it reads as guidance rather
   than as another control in the bar. */
.bulkhint
{
    font-size: 0.85em;
    color: #444444;
}
/* Publishing state and link, shown inside a gallery the owner is viewing. */
.gallerypub
{
    margin: 6px 0px 9px 0px;
    padding: 6px;
    border: 1px dotted #000000;
}
.gallerylinkbox
{
    word-wrap: break-word;
    overflow-wrap: anywhere;
}

/* --- mail aliases --- */
/* One row per alias, with its buttons in the last cell. A table rather than
   a list because there are four facts per row and they line up.
   
   Ruled rather than plain: an address, a destination and a state read as
   one run-on line without something between them, and the destination is
   long enough to wrap. The dotted 1px black is the same enclosure .authbox
   uses elsewhere on this page, so the two do not look like two different
   people's work. */
.aliastable
{
    border-collapse: collapse;
    margin: 6px 0px;
    width: 100%;
}
.aliastable th
{
    text-align: left;
    font-weight: normal;
    padding: 3px 6px;
    border: 1px dotted #000;
}
.aliastable td
{
    padding: 3px 6px;
    border: 1px dotted #000;
    vertical-align: middle;
    /* A destination can be 255 characters with no space in it, which would
       otherwise push the table wider than the page.
       
       overflow-wrap, NOT word-break: break-all. break-all breaks ANY word
       at the edge of its box whether or not it needed to, which turned
       "alice@0wx.org" into "alice@0wx.or / g" and "5 minutes" into
       "5 m / inutes". overflow-wrap: anywhere only breaks a word that
       cannot fit on a line of its own, which is the case this is for. */
    overflow-wrap: anywhere;
}
/* An ordinary address should not wrap at all.
   
   Left to itself the table gives this column its minimum width and lets the
   buttons take the rest, so "alice@0wx.org" broke across two lines while
   there was space to spare. A floor here, and one for the destination, and
   the long values still wrap because of the overflow-wrap above. */
.aliastable td:first-child,
.aliastable th:first-child
{
    min-width: 11em;
}

/* Alternating rows as well as the rules. Either alone is enough to follow a
   row across; together they survive a narrow screen, where the buttons wrap
   and a row becomes two lines tall.
   
   #f0f0f0 is the shade this stylesheet already uses for a raised surface --
   inputs, buttons, the menu items. Picking a new one would have been a
   second grey nobody chose. */
.aliastable tr:nth-child(even) td
{
    background-color: #f0f0f0;
}

/* The buttons in the last cell are each their own form, because they post
   to different actions. Inline, so they read as a row of buttons rather
   than as three stacked forms. */
.inlineform {
    display: inline;
    margin: 0 0.2em 0 0;
}

.textinput {
    padding: 0.3em;
    max-width: 22em;
}

.note {
    opacity: 0.75;
    font-size: 0.92em;
}

/* --- audio tags over the thumbnail --- */
/* The link around the thumbnail is the positioning context, so the overlay
   sits on the picture rather than under it. .fileitem is already
   position:relative for the selection checkbox, and using that instead
   would put these over the whole tile including the filename. */
.fileitem a
{
    position: relative;
    display: inline-block;
}
.audiotags
{
    position: absolute;
    left: 0px;
    right: 0px;
    /* Centred on the thumbnail rather than sitting along its bottom edge.
       
       top:50% puts the box's TOP at the middle, which is half a box too
       low; the translate pulls it back by half its own height, whatever
       that turns out to be. That matters here because the box is one, two
       or three lines depending on how many tags the file carries. */
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, 0.45);
    color: #ffffff;
    /* A shadow, now that the background is thinner: over a pale thumbnail
       0.45 alone leaves white text on near-white, and the shadow is what
       keeps it readable without darkening the picture again. */
    text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.9);
    padding: 4px 5px;
    text-align: center;
    font-size: 0.8em;
    line-height: 1.3;
    /* Not clickable-looking: the whole thumbnail is already a link, and the
       overlay must not swallow the pointer. */
    pointer-events: none;
}
.audiotags span
{
    display: block;
    /* A title can be 200 characters. One line each, clipped. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* The first line is the title, and is the one worth reading first. */
.audiotags span:first-child
{
    font-weight: bold;
}

/* --- a paste, rendered as a page --- */
.pastebody
{
    margin: 0px;
    padding: 0px;
}
.pastehead
{
    padding: 6px 10px;
    border-bottom: 1px solid #000000;
    background-color: #e0e0e0;
}
.pastename
{
    font-weight: bold;
    margin-right: 8px;
}
.pastelang
{
    opacity: 0.7;
    margin-right: 8px;
}
.pastecode
{
    /* A gap above, or the raw button in the heading sits directly on the
       first line of the paste and overlaps it by the button's border. */
    margin: 8px 0px 0px 0px;
    /* counter-reset here rather than on the code element: the counter has
       to exist before the first line increments it. */
    counter-reset: pasteline;
    overflow-x: auto;
    background-color: #ffffff;
}
/* One line. The line NUMBER is drawn by a counter and is NOT in the markup,
   so selecting the code and copying it does not take the numbers with it --
   which is the single most irritating thing about most pastebins. */
.pl
{
    display: block;
    counter-increment: pasteline;
    padding: 0px 8px 0px 0px;
}
.pl:before
{
    content: counter(pasteline);
    display: inline-block;
    width: 3.5em;
    padding-right: 8px;
    margin-right: 8px;
    text-align: right;
    border-right: 1px solid #cfcfcf;
    color: #808080;
    /* The number is decoration, not content: it must not be selectable
       either, or a triple-click still catches it in some browsers. */
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;
}
/* Zebra striping, so a long line that wraps is still visibly one line. */
.pl:nth-child(even)
{
    background-color: #f4f4f4;
}
/* Syntax colours. Chosen to stay legible on both the white and the striped
   rows, which rules out anything pale. */
.hc { color: #707070; font-style: italic; }   /* comment */
.hs { color: #a03000; }                       /* string  */
.hk { color: #0000c0; font-weight: bold; }    /* keyword */
.hn { color: #008060; }                       /* number  */
/* Markup. A tag and an attribute have to be told apart at a glance, which
   is most of what reading XML is, so they get different weights as well as
   different colours. */
.ht { color: #0000c0; font-weight: bold; }    /* tag name  */
.ha { color: #7a0080; }                       /* attribute */
.he { color: #008060; }                       /* entity    */

/* --- the duplicates listing --- */
/* A table rather than a grid, because the point is comparing the names and
   dates of copies that are otherwise identical -- and those line up. */
.dupetable
{
    border-collapse: collapse;
    margin: 6px 0px;
    width: 100%;
}
.dupetable th
{
    text-align: left;
    font-weight: normal;
    padding: 3px 6px;
    border: 1px dotted #000000;
}
.dupetable td
{
    padding: 3px 6px;
    border: 1px dotted #000000;
    vertical-align: top;
    overflow-wrap: anywhere;
}
/* The four cells that span the group are centred vertically against the
   names beside them, so a group of six copies does not leave its thumbnail
   stranded at the top. */
.dupthumb, .dupcount
{
    vertical-align: middle;
    text-align: center;
}
.dupthumb img
{
    max-width: 96px;
    max-height: 96px;
    display: block;
}
.dupcount
{
    font-weight: bold;
}
.dupdate
{
    white-space: nowrap;
}
/* NOT .filesel, which is position:absolute so it can sit over the corner of
   a thumbnail in the grid. Dropped into a table cell it leaves the flow
   entirely and positions itself against the nearest positioned ancestor --
   which here is nothing, so it lands somewhere off the table and reads as
   a missing checkbox rather than a misplaced one.
   
   In this table the checkbox belongs beside the name, in the flow, which is
   what a plain inline element already does. */
.dupsel
{
    margin: 0px 4px 0px 0px;
    vertical-align: baseline;
}

/* The gallery a copy lives in, shown as a path in front of the name.
   
   Dimmed, because the name is what is being compared and the path is
   context. Not hidden: the reason a duplicate goes unnoticed is usually
   that one copy is in a gallery nobody was looking at. */
.dupwhere
{
    /* 0.5, measured in a browser rather than guessed.
       
       0.7 was chosen because it is what .note uses elsewhere, and .note is
       dimming a whole paragraph away from body text. This is dimming a few
       characters that sit immediately against the thing they must not be
       confused with, so it has to be further down. */
    opacity: 0.5;
}

/* A rule above each group, so where one ends and the next begins is
   visible even when both hold the same number of copies. */
.dupetable tr.dupgroup td
{
    border-top: 1px dotted #000000;
}

/* The update link is a URL with a 32-character key in it and no spaces, so
   it would push the table wider than the page if left alone. */
.dnskey
{
    max-width: 22em;
    overflow-wrap: anywhere;
    font-size: 0.85em;
}
