/*
 * This file is part of NetSurf, http://netsurf-browser.org/
 */

/* Elements ordered as in the HTML 4.01 specification. */

html { display: block; }

head { display: none; }

/* No line-height here: it inherits into every element on the page and so
 * overrides `normal`, which is now the font's own ascent+descent. Pinning it
 * to 1.33 added ~2px to every line box against what other browsers draw. */
body { display: block; margin: 8px; }

div { display: block; }

h1 { display: block; font-size: 2em; font-weight: bold; margin: .67em 0; }
h2 { display: block; font-size: 1.5em; font-weight: bold; margin: .69em 0; }
h3 { display: block; font-size: 1.17em; font-weight: bold; margin: .83em 0; }
h4 { display: block; font-weight: bold; margin: 1.12em 0; }
h5 { display: block; font-size: .83em; font-weight: bold; margin: 1.5em 0; }
h6 { display: block; font-size: .75em; font-weight: bold; margin: 1.67em 0; }

/* KolibriOS <kosicon n=X> extension: the icon is an inline element.
 * System icons are always 18x18, so state that here: layout then knows the
 * size before the fetch completes and surrounding text doesn't reflow.
 *
 * Centre it on the text. Neither keyword does that on its own: baseline stands
 * the icon's bottom edge on the baseline, which pushes an 18px icon half its
 * height above a label whose capitals are only ~13px, while middle -- per CSS,
 * the box's midpoint half an x-height above the baseline -- leaves that midpoint
 * ~4px up where the capitals' midpoint is ~6.5px up, so the icon hangs below the
 * baseline instead. The icon is always 18px, so make up the difference with a
 * fixed nudge, as board.kolibrios.org does for its own navbar icons.
 *
 * This is only safe because KOSICON is a void element in the treebuilder. While
 * it was an unknown element it stayed on the stack of open elements and
 * swallowed everything after it, so this rule landed on that text too and
 * raised ": 3413" 3px off "CPU" in the same BirdBench heading. */
kosicon { display: inline; vertical-align: middle;
	  position: relative; top: -2px;
	  width: 18px; height: 18px; }

/* Links show the pointing hand. Browsers put this in their UA stylesheet;
 * NetSurf otherwise only infers POINT for cursor:auto links, so a site that
 * inherits a non-auto cursor onto its links (e.g. phpBB) loses the hand. */
a:link, a:visited { cursor: pointer; }

/* Same for the clickable form controls. get_pointer_shape() only infers the
 * hand from cursor:auto for GADGET_SUBMIT and GADGET_IMAGE, so <button>,
 * type=button/reset and <select> were left with the plain arrow -- which is
 * what "hovering a button gives no hand" looks like. Stating it here also
 * covers the case where a page inherits a non-auto cursor onto the control. */
button,
input[type="submit"], input[type="button"], input[type="reset"],
input[type="checkbox"], input[type="radio"],
select { cursor: pointer; }

address { display: block; font-style: italic; }

em { font-style: italic; }
strong { font-weight: bold; }
dfn { font-style: italic; text-decoration: underline; }
code { font-family: monospace; }
samp { font-family: monospace; }
kbd { font-family: monospace; font-weight: bold; }
var { font-style: italic; }
cite { font-style: italic; }
abbr { font-variant: small-caps; }
acronym { font-variant: small-caps; }

blockquote { display: block; margin: 1.12em 40px;}

q { font-style: italic; }

sub { vertical-align: sub; font-size: .83em; }
sup { vertical-align: super; font-size: .83em; }

p { display: block; margin: 1.12em 0; }

br[clear=left] { clear: left; }
br[clear=right] { clear: right; }
br[clear=all] { clear: both; }

pre { display: block; font-family: monospace; white-space: pre; margin-bottom: 1em; }

ins { color: green; text-decoration: underline; }
del { color: red; text-decoration: line-through; }

ul { display: block; padding-left: 40px; margin: 1.12em 0;
	list-style-type: disc; }
ol { display: block; padding-left: 40px; margin: 1.12em 0;
	list-style-type: decimal; }
li { display: list-item; }

ul ul { list-style-type: circle; }
ul ul ul { list-style-type: square; }

ol ul, ul ol, ul ul, ol ol { margin-top: 0; margin-bottom: 0; }

/* Browsers indent a <dd> with margin-left and give <dl>/<dt> no padding at
 * all. Doing it with padding instead made the indent unresettable: a page
 * that zeroes the margin (stackexchange's .ml0) still got shifted, and every
 * definition list on such a site sat 1.5em + 1em too far right. */
dl { display: block; margin: 1em 0; }
dt { display: block; }
dd { display: block; margin-left: 40px; }

dir { display: block; padding-left: 1.5em; margin: 1.12em 0; }
menu { display: block; padding-left: 1.5em; margin: 1.12em 0; }

table { display: table; border-spacing: 2px; }

table[border], table[border] td, table[border] tr { border-color: grey; }

caption { display: table-caption; }

thead { display: table-header-group; vertical-align: middle; }
tfoot { display: table-footer-group; vertical-align: middle; }
tbody { display: table-row-group; vertical-align: middle; }

colgroup { display: table-column-group; }
col { display: table-column; }

table > tr { vertical-align: middle; }

tr { display: table-row; vertical-align: inherit; }
td, th { display: table-cell; vertical-align: inherit; padding: 1px; }
th { font-weight: bold; text-align: center; }

a:link { color: #00f; text-decoration: underline; }
a:visited { color: #609; }

img { color: #888; }

center { display: block; }

tt { font-family: monospace; }
i { font-style: italic; }
b { font-weight: bold; }
big { font-size: 1.17em; }
small { font-size: .83em; }
strike, s { text-decoration: line-through; }
u { text-decoration: underline; }

hr { display: block; margin: 0.5em auto; border: 1px inset #888; }
hr[noshade] { border-style: solid; }

noframes { display: none; }

iframe { width: 19em; height: 10em; }

form { display: block; }

/* Form controls carry no margin of their own (Chrome and Firefox: `margin:
 * 0em`); a 1px one made a stretched flex-row <select> 2px shorter than
 * its row, which tests/ebayhdr.html measures. */
input, button { background-color: #fff; color: #000; text-align: left;
	font-family: sans-serif; width: auto; height: auto;
	border: 1px solid #949ea8;
	padding: 2px 4px; line-height: 1.33;
	margin: 0; box-sizing: border-box; }
/* overflow:hidden keeps a text field's value inside its frame, and that is
 * the only place it belongs. No real browser puts it on <button>, and every
 * modern dropdown hangs its popup off one: gitea's "Add File" is
 * `<button class="ui dropdown">` with an absolutely positioned `.menu` child,
 * so the 18px-tall button clipped away the whole 128x120 menu. The menu was
 * laid out, visible and in the right place -- it was only ever the paint clip
 * that hid it. */
input { overflow: hidden; }
/* A KolibriOS button rather than the CSS2 bevel. `2px outset #d9d9d9` is the
 * appearance Netscape shipped, and next to the widgets the frontend now paints
 * it was the last thing on a page still dated to the nineties.
 *
 * The palette is the system one (kernel fn 48.3, see kolibri_syscolors.c):
 * button face #ddd, button text #000, line #999. The face is that colour lit
 * from above, and the bottom border is a step darker than the sides, which is
 * where the slight bulge comes from -- the same two cues the desktop's own
 * widgets use, done with paint rather than with an `outset` bevel.
 *
 * The ramp itself is NOT written here. linear-gradient() reaches the box
 * through a stylesheet source rewrite, and that rewrite only runs over author
 * sheets, so a gradient in this file parses to nothing at all. box_construct.c
 * builds it instead, keyed on exactly this background-color -- change the
 * colour here and you must change it there. A page that gives its buttons a
 * background of their own therefore keeps it, unpainted over. */
input[type=button], input[type=reset], input[type=submit], button {
	background-color: #dddddd; color: #000; text-align: center;
	border: 1px solid #9a9a9a; border-bottom-color: #7d7d7d;
	padding: 2px 0.7em; }
input[type=image] { background-color: transparent; color: #000;
	border: none; padding: 0 2px; box-sizing: content-box; }
/* A native checkbox/radio is painted by the frontend into its content box, and
 * the padding is not something an author can put inside it -- Blink and Gecko
 * both drop it (used value 0) while `appearance` stays at its default. We must
 * do the same, and with !important, because the drawn square IS the content
 * box: tomshardware.com's newsletter opt-ins are
 * `input[type=checkbox]{width:13px;height:13px;padding:0 0 10px 25px}` over the
 * border-box sizing below, so 25px of padding-left ate the whole 13px and the
 * checkbox was drawn 0 pixels wide -- nothing appeared beside either label.
 * Horizontal breathing space next to the label text is a margin, not padding,
 * so it survives being overridden by a page that means to place the control. */
input[type=checkbox], input[type=radio] { background-color: transparent;
	border: none; padding: 0 !important; margin: 1px 0.1em; }
input[type=file] { background-color: #dddddd; color: #000;
	border: 1px solid #9a9a9a; border-bottom-color: #7d7d7d;
	padding: 2px 6px; }
/* :disabled rather than [disabled]: the pseudo-class is the spec's "actually
 * disabled" state, so this also greys the controls inside a
 * `<fieldset disabled>`, which carry no attribute of their own.
 *
 * It sits AFTER every rule that gives a control its own background, because
 * `input[type=submit]` and `input:disabled` have the same specificity and the
 * later one wins: above them, a disabled submit button kept its live colour
 * while a disabled <button> greyed, since `button` alone is weaker. The
 * checkbox and radio then have to be exempted explicitly rather than by
 * ordering -- the native widget is painted over that background. */
/* A different grey from the button face on purpose: that exact colour is what
 * box_construct.c keys the painted ramp off, so leaving it here would have
 * given a disabled button the lit face and greyed only its label -- which
 * reads as a live button with odd text. Flat is the whole point. */
input:disabled, button:disabled { background-color: #e6e6e6; color: #888;
	background-image: none; border-color: #b5b5b5; }
input[type=checkbox]:disabled, input[type=radio]:disabled {
	background-color: transparent; }
input[align=left] { float: left; }
input[align=right] { float: right; }

select { background-color: #d9d9d9; color: #000; text-align: left;
	font-family: sans-serif; width: auto; height: auto; overflow: hidden;
	border: medium inset #d9d9d9; padding: 1px 3px 1px 2px;
	white-space: nowrap; margin: 0; }
/* The dropdown arrow is NOT a pseudo element. It used to be written here as
 * `select:after { content: "\25bc" }`, and never appeared on any page: a
 * select is IS_REPLACED and ends its conversion with `*convert_children =
 * false`, and box_construct.c generates no ::after for either. Layout still
 * reserved SCROLLBAR_WIDTH for it, so every dropdown carried sixteen empty
 * pixels. It is painted by html_redraw_select_arrow() now, next to the
 * checkbox and the radio. */
select:disabled { background-color: #ddd; color: #666; }

/* A list box (`multiple`, or `size` greater than one) is not a dropdown:
 * box_select() gives it one line per option and this scrolls them. No arrow
 * either -- there is no menu behind it to open. The height comes from the
 * size= presentational hint in css/hints.c. */
select[multiple], select[size]:not([size="1"]) {
	background-color: #fff; overflow-x: hidden; overflow-y: auto;
	border: 2px inset #d9d9d9; padding: 0 2px; cursor: default; }

textarea { background-color: #fff; color: #000; text-align: left;
	font-family: monospace; width: auto; height: auto; overflow: auto;
	margin: 0; border: 1px solid #949ea8;
	padding: 2px 4px; }
textarea:disabled { background-color: #ddd; color: #666; }

/* <progress> and <meter> are replaced elements here: box_special.c drops
 * their children (which are fallback text for browsers that lack the tag)
 * and redraw.c paints the bar. The sizes are the ones every engine settled
 * on, so a page that positions them by CSS lands in the same place. */
progress, meter { display: inline-block; width: 10em; height: 1em;
	vertical-align: -0.2em; margin: 0 0.1em; border: none; padding: 0; }

fieldset { display: block; border: 1px solid #d5d9de; margin: 1.12em 0;
	padding: 0.35em 0.75em 0.625em; }
/* The first legend of a fieldset is not laid out inside its frame: it sits ON
 * the block-start border, which is drawn with a gap behind it. box_legend()
 * marks it, layout lifts it onto the border edge and redraw runs the border
 * round it. It has to be a BLOCK for any of that to mean anything -- left
 * inline (which is what it used to be here, by omission) the checkboxes that
 * follow ran on the same line as the caption. The 2px is Chrome's.
 *
 * It has to be SHRINK-TO-FIT as well, because the gap in the border is the
 * width of its margin box: a legend filling the line opens that gap across
 * the whole top of the frame. In a block fieldset layout does it (the
 * IS_LEGEND arm of layout_block_find_dimensions); in a flex or grid one the
 * legend is an ITEM and would stretch across the cross axis, which is what
 * align-self/justify-self are here for. Chrome takes the legend out of flex
 * layout entirely; sizing it to its content is the same picture. */
legend { display: block; padding-left: 2px; padding-right: 2px;
	align-self: start; justify-self: start; }

noembed, script, style, title { display: none; }

/* Metadata content renders nothing wherever it sits (HTML rendering section).
 * `head { display: none }` above covers the usual place, but a <link> is also
 * legal in the body -- and a declarative shadow root routinely carries several,
 * one per stylesheet the component needs. Rendered, each became a box: inside
 * nytimes' video carousel (a `display:contents` grid) the <link> took the first
 * grid column and shoved every video card one place along. */
area, base, basefont, datalist, link, meta, param, rp { display: none; }

/* Media elements.
 *
 * <source> and <track> used to be `display: none` here, on the reasoning
 * that they are metadata for their parent and render nothing. They do render
 * nothing -- but "nothing" and "no box" are different, and browsers mean the
 * second only inside <video>/<audio>, whose children are fallback content
 * and are not rendered at all. Measured in Chrome (tests/sourcebox.html):
 * a <source> is `display: inline` everywhere, and inside a <picture> it has
 * a real client rect -- zero-width, one line tall, at the picture's own
 * position.
 *
 * That rect is what the whole lazy-<picture> idiom is built on:
 *
 *     new IntersectionObserver(...).observe(el)   // el is a `.lazy > source`
 *     ... entry.isIntersecting -> source.srcset = source.dataset.srcset
 *
 * With no box the observer can only ever answer "not intersecting", so on
 * thegoodocs.com 112 of the 114 card images never loaded -- the two that did
 * were the ones the server had already marked `loaded-success` (2026-08-30).
 * An empty inline costs no line height (a line box with nothing in it stays
 * empty), so giving them boxes changes no layout.
 *
 * Inside <video> the children are still not converted -- see box_video() in
 * box_special.c -- so those keep answering with no rect, as Chrome does.
 *
 * <video> is inline-block so that a poster fills it and the width/height
 * attributes have something to size -- box_video() draws the poster and,
 * failing that, lets the element's fallback content through.
 *
 * <audio> without `controls` has no box in any browser (Chrome's UA sheet:
 * `audio:not([controls]) { display: none !important }`); it still plays,
 * driven by script, through the box-less fetch the HTMLMediaElement binding
 * starts. With `controls` it is a bar -- image/video.c draws one -- at the
 * size browsers give theirs. */
video { display: inline-block; }
audio { display: none; }
audio[controls] { display: inline-block; width: 300px; height: 32px; }

/* HTML5 elements */
/* `search` is the newest of these (HTML Living Standard, 2023); nike.com
 * wraps its whole header search bar in one, and without the rule the bar
 * came out as an inline box wrapping block children. */
article, aside, figcaption, figure, footer, header, main, nav, search,
section {
	display: block;
}

mark {
	background: yellow;
	color: black;
}

/* KolibriOS port: <details>/<summary> disclosure widgets. NetSurf has no
 * interactive toggling for them, so render the spec DEFAULT state: a
 * details element without the open attribute shows only its summary
 * (e.g. bbc.com's no-JS burger menu is a closed <details>; without this
 * rule it rendered permanently expanded over the page). */
details:not([open]) > *:not(summary) { display: none; }
details { display: block; }
summary { display: block; }

/* KolibriOS port: <template> content is inert per spec and must never
 * render; also hide <dialog> without the open attribute. A declarative
 * shadow root's template is handled separately (html/shadow.c) -- it is
 * never visited, so this rule does not reach it. */
template, dialog:not([open]) { display: none; }

/* The HTML popover attribute. Chrome opens one.com's "24/7 support"
 * menu with scripting off because the whole widget is declarative:
 * <button popovertarget=X> next to <div id=X popover=auto>. The UA
 * rules are what hide the panel until it is shown and what place it
 * once it is; the author sheet then only overrides what it wants
 * (one.com drops the border, padding and margin).
 *
 * A real top layer would take the panel out of the page entirely. We
 * approximate it with position:fixed and a z-index above every stacking
 * context an author is likely to build -- including the sticky,
 * z-index:1000 header this menu hangs off.
 *
 * The value is picked to survive libcss keeping z-index as a fixed-point
 * number with 10 fractional bits. The STACKED trace has reported this
 * same box as both 1024000000 (scaled) and 1000000 (raw) on different
 * runs, and one.com's header is `z-index:1000` -- 1024000 scaled. Read
 * raw against a scaled header, 1000000 LOSES. 2000000 wins either way,
 * and still fits int32 once scaled (2048000000 < 2147483647), which
 * INT32_MAX itself did not.
 *
 * DELIBERATELY NOT the spec's `inset:0; width:fit-content;
 * height:fit-content; margin:auto`, which is how a browser centres a
 * popover. `height:fit-content` is not implemented here, so it fell back
 * to auto -- and an auto height between `top:0` and `bottom:0` resolves
 * to the full viewport. one.com's panel came out 412x611: a transparent,
 * full-height box lying over the left half of the page that swallowed
 * every click, so the menu could not be closed and nothing behind it
 * could be pressed. With only `top` and `left` set, auto height is the
 * content height, which is what fit-content wanted in the first place.
 * The cost is that a popover with default margins sits at the top left
 * instead of centred; a page that positions its own panel (every real
 * one, one.com included) is unaffected. */
[popover] {
	position: fixed; z-index: 2000000;
	top: 0; left: 0;
	width: fit-content;
	border: 1px solid; padding: 0.25em;
	overflow: auto; color: black; background-color: white;
}
[popover]:not(:popover-open) { display: none; }

/* A slot is a placeholder: it contributes no box of its own, only the
 * children assigned to it. */
slot { display: contents; }

/* The global `hidden` content attribute (HTML5 rendering section). This is a
 * different thing from `<input type=hidden>`, which box_input() already drops
 * without a box -- and it was missing, so bbc.co.uk/search rendered its
 * `<input hidden readonly name=d value=search_ps>` as a real, editable text
 * field sitting next to the Search button.
 *
 * `hidden=until-found` is here too, though per spec it is
 * `content-visibility: hidden` rather than `display: none` -- the box stays,
 * its CONTENTS are skipped, and find-in-page may reveal them. There is no
 * content-visibility in this engine, and of the two things it could be, not
 * rendering the subtree is the one that matches what the user sees in
 * Chrome. Rendering it is not a near miss either: browserscore.dev parks 526
 * collapsed subtrees in `hidden=until-found` divs as raw JSON with no spaces
 * in it, and each unbreakable 8000px line went into the automatic minimum
 * size of the flex item holding it -- the document came out 8255px wide the
 * moment an accordion was opened. */
[hidden] { display: none; }

/* KolibriOS port: JS-collapsing overflow menus (Gitea's repository tab bar,
 * `<overflow-menu>`). The author styles the strip as a NOWRAP flex row
 * (`.overflow-menu-items{display:flex;flex:1}`) and relies on javascript to
 * measure it and move whatever does not fit into a "..." popup. With no
 * javascript nothing is moved, and since a flex item never shrinks below its
 * min-content width the strip simply overhangs its container: on
 * git.kolibrios.org the last tab ended 1px past a 997px viewport, which was
 * enough to raise a horizontal scrollbar over the whole page (the same one
 * pixel on /pulls, /issues -- every repository page). Let the strip wrap
 * instead; every tab stays reachable and the page keeps its width. */
.overflow-menu-items { flex-wrap: wrap; }
