/********************************************************************** * **********************************************************************/ /******************************************************** Settings ***/ @ribbon-mark-offset: 5px; @ribbon-mark-size: 10px; @single-image-indicator-size: 10px; /********************************************************** Mixins ***/ .user-select (@mode: auto) { -moz-user-select: @mode; -webkit-user-select: @mode; -o-user-select: @mode; -ms-user-select: @mode; user-select: @mode; } .origin (@x:top, @y:left) { -webkit-transform-origin: @arguments; -ms-transform-origin: @arguments; transform-origin: @arguments; } .transform (@deg:0deg, @scaleX:1, @scaleY:1) { -webkit-transform: rotate(@deg) scaleY(@scaleY) scaleX(@scaleX); -moz-transform: rotate(@deg) scaleY(@scaleY) scaleX(@scaleX); -o-transform: rotate(@deg) scaleY(@scaleY) scaleX(@scaleX); -ms-transform: rotate(@deg) scaleY(@scaleY) scaleX(@scaleX); transform: rotate(@deg) scaleY(@scaleY) scaleX(@scaleX); } .rotate (@deg) { .transform(@deg) } .flipped-vertically () { .transform(0deg, 1, -1) } .flipped-horizontally () { .transform(0deg, -1, 1) } /********************************************************* utility ***/ .expanding-text .hidden { display: none; } .expanding-text:hover .shown { display: none; } .expanding-text:hover .hidden { display: inline; } /*********************************************************************/ body { font-family: sans-serif; padding: 0px; margin: 0px; } /************************************************************** UI ***/ .title-bar { display: block; position: fixed; content: ""; top: 0px; left: 0px; height: 20px; width: 100%; color: white; background: black; overflow: hidden; opacity: 0; z-index: 10000; /* node-webkit */ -webkit-app-region: drag; } .title-bar:hover { opacity: 1; } .title-bar .title { display: inline-block; float: left; height: 20px; width: auto; color: white; background: transparent; font-size: 11px; font-style: italic; font-weight: bold; vertical-align: middle; text-align: left; margin: 2px; margin-left: 10px; } .title-bar .button { display: inline-block; float: right; width: 20px; height: 20px; color: white; background: transparent; font-size: 18px; vertical-align: middle; /* node-webkit */ -webkit-app-region: no-drag; } .title-bar .button:hover { cursor: hand; } .title-bar .close:hover { color: red; } /* .full-screen-mode .title-bar { display: none; } */ /********************************************************** Viewer ***/ .viewer { position: relative; width: 100%; height: 100%; overflow: hidden; /*border: solid blue 1px;*/ box-sizing: border-box; .user-select(none); } /****************************************************** Ribbon set ***/ .ribbon-set { position: absolute; display: block; /* NOTE: this needs for scaling/zooming to behave correctly and not shift the element, when its dimensions change... ...this is because .ribbon-set will both be used for scaling and aligning... */ .origin(top, left); } .ribbon-set:empty:after { display: block; top: 0px; left: 0px; width: 100%; height: 100%; content: "Empty"; text-align: center; } /********************************************************** Ribbon ***/ .ribbon { position: relative; display: block; height: auto; min-width: 0px; overflow: visible; white-space: nowrap; font-size: 0; margin-top: 20px; margin-bottom: 20px; } .ribbon:empty { display: none; } .ribbon:first-child { margin-top: 0px; } .ribbon:last-child { margin-bottom: 0px; } /*********************************************************** Image ***/ .image { position: relative; display: inline-block; vertical-align: middle; text-align:left; width: 300px; height: 300px; font-size: 12pt; overflow: hidden; box-sizing: border-box; color: white; text-shadow: black 0.1em 0.1em 0.4em, black 0.1em 0.1em; background: no-repeat 50% black; background-size: contain; /* XXX do we need this? */ border: solid black 5px; } .current.image { background: no-repeat 50% black; background-size: contain; /* XXX remove this... */ border: solid red 5px; } /* image turning... */ /* NOTE: need to account for proportions after turning... */ .image[orientation="90"] { .rotate(90deg); } .image[orientation="180"] { .rotate(180deg); } .image[orientation="270"] { .rotate(270deg); } /* Flipped vertically only... */ /* NOTE: wee need to do all possible combinations here as we can't combine different parts of a transform attr from different classes */ .image[flipped*="vertical"] { .flipped-vertically; } .image[orientation="90"][flipped="vertical"] { .transform(90deg, 1, -1) } .image[orientation="180"][flipped="vertical"] { .transform(180deg, 1, -1) } .image[orientation="270"][flipped="vertical"] { .transform(270deg, 1, -1) } /* Flipped horizontally only... */ .image[flipped*="horizontal"] { .flipped-horizontally; } .image[orientation="90"][flipped="horizontal"] { .transform(90deg, -1) } .image[orientation="180"][flipped="horizontal"] { .transform(180deg, -1) } .image[orientation="270"][flipped="horizontal"] { .transform(270deg, -1) } /* Flipped vertically and horizontally... */ .image[flipped*="vertical"][flipped*="horizontal"] { .transform(0deg, -1, -1) } .image[orientation="90"][flipped*="vertical"][flipped*="horizontal"] { .transform(90deg, -1, -1) } .image[orientation="180"][flipped*="vertical"][flipped*="horizontal"] { .transform(180deg, -1, -1) } .image[orientation="270"][flipped*="vertical"][flipped*="horizontal"] { .transform(270deg, -1, -1) } /* default backgrounds */ /* XXX not sure if we need these... .image { background-image: url(images/loading.gif); } .image[orientation="90"] { background-image: url(images/loading-90deg.gif); } .image[orientation="180"] { background-image: url(images/loading-180deg.gif); } .image[orientation="270"] { background-image: url(images/loading-270deg.gif); } */ /***************************************************** Image marks ***/ .marks-visible.viewer .marked.image:after { display: block; position: absolute; content: ""; font-size: 0pt; border: none; width: @ribbon-mark-size; height: @ribbon-mark-size; top: auto; bottom: @ribbon-mark-offset; left: auto; right: @ribbon-mark-offset; border-radius: 50%; background: blue; } .marks-visible.viewer .marked.image[orientation="270"][flipped*="vertical"][flipped*="horizontal"]:after, .marks-visible.viewer .marked.image:not([orientation])[flipped*="vertical"]:after, .marks-visible.viewer .marked.image[orientation="0"][flipped*="vertical"]:after, .marks-visible.viewer .marked.image[orientation="180"][flipped="horizontal"]:after, .marks-visible.viewer .marked.image[orientation="90"]:not([flipped]):after { top: @ribbon-mark-offset; bottom: auto: left: auto; right: @ribbon-mark-offset; } .marks-visible.viewer .marked.image:not([orientation])[flipped*="vertical"][flipped*="horizontal"]:after, .marks-visible.viewer .marked.image[orientation="0"][flipped*="vertical"][flipped*="horizontal"]:after, .marks-visible.viewer .marked.image[orientation="270"][flipped="vertical"]:after, .marks-visible.viewer .marked.image[orientation="90"][flipped="horizontal"]:after, .marks-visible.viewer .marked.image[orientation="180"]:not([flipped]):after { top: @ribbon-mark-offset; bottom: auto; left: @ribbon-mark-offset; right: auto; } .marks-visible.viewer .marked.image[orientation="90"][flipped*="vertical"][flipped*="horizontal"]:after, .marks-visible.viewer .marked.image[orientation="180"][flipped="vertical"]:after, .marks-visible.viewer .marked.image:not([orientation])[flipped*="horizontal"]:after, .marks-visible.viewer .marked.image[orientation="0"][flipped*="horizontal"]:after, .marks-visible.viewer .marked.image[orientation="270"]:not([flipped]):after { top: auto; bottom: @ribbon-mark-offset; left: @ribbon-mark-offset; right: auto; } /* NOTE: we use a different mark representation for single image mode... */ .marks-visible.single-image-mode.viewer .marked.image:after { display: none; } /* corner mark... (a-la bookmarks in PortableMag) * XXX account for flipping... */ /* @ribbon-mark-offset: -15px; .marks-visible.viewer .marked.image:after { display: block; position: absolute; content: ""; font-size: 0pt; border: none; width: 30px; height: 30px; top: @ribbon-mark-offset; right: @ribbon-mark-offset; background: blue; .rotate(45deg) } .marks-visible.viewer .marked.image[orientation="90"]:after { top: @ribbon-mark-offset; left: @ribbon-mark-offset; } .marks-visible.viewer .marked.image[orientation="180"]:after { bottom: @ribbon-mark-offset; left: @ribbon-mark-offset; } .marks-visible.viewer .marked.image[orientation="270"]:after { bottom: @ribbon-mark-offset; right: @ribbon-mark-offset; } */ /* XXX should we use opacity??? */ .marked-only-view.viewer:not(.marks-visible) .image:not(.marked) { opacity: 0.3; } /****************************************************** Image info ***/ .image .inline-image-info { display: none; position: absolute; bottom: 0px; width: 100%; background: black; opacity: 0.7; } .image .inline-image-info:hover { .user-select(auto); } .image .inline-image-info::selection { color: white; background: red; } .image-info-visible.viewer .global-image-info, .image-info-visible.viewer .image:hover .inline-image-info { display: block; } .single-image-mode.viewer .image:hover .inline-image-info { display: none; } .image[orientation="90"] .inline-image-info { top: auto; left: 100%; .origin(bottom, left); .rotate(-90deg); } .image[orientation="180"] .inline-image-info { top: 0px; bottom: auto; .rotate(180deg); } .image[orientation="270"] .inline-image-info { top: auto; left: auto; right: 100%; .origin(bottom, right); .rotate(90deg); } /* compensate for flipping... */ /* XXX START: I hate this code, will think if a better way to do this... */ .image:not([orientation="90"])[flipped*="horizontal"] .inline-image-info { .flipped-horizontally; } .image[orientation="90"][flipped*="horizontal"] .inline-image-info { top: auto; bottom: 100%; left: -100%; right: auto; .origin(bottom, right); .transform(90deg, -1, 1); } .image[orientation="180"][flipped*="horizontal"] .inline-image-info { top: auto; bottom: 100%; left: 0px; right: auto; .origin(bottom, right); .transform(180deg, -1, 1); } .image[orientation="270"][flipped*="horizontal"] .inline-image-info { top: auto; bottom: 0px; left: 0px; right: auto; .origin(bottom, right); .transform(270deg, -1, 1); } .image[flipped*="vertical"] .inline-image-info { top: 0px; bottom: auto; .flipped-vertically; } .image[orientation="90"][flipped*="vertical"] .inline-image-info { top: auto; bottom: 100%; left: 100%; right: auto; .origin(bottom, left); .transform(-270deg, 1, -1); } .image[orientation="180"][flipped*="vertical"] .inline-image-info { top: auto; bottom: 0px; left: -100%; right: auto; .origin(bottom, right); .transform(180deg, 1, -1); } .image[orientation="270"][flipped*="vertical"] .inline-image-info { top: auto; bottom: 100%; left: -100%; right: auto; .origin(bottom, right); .transform(270deg, 1, -1); } .image[flipped*="vertical"][flipped*="horizontal"] .inline-image-info { top: 0px; bottom: auto; .transform(0deg, -1, -1); } .image[orientation="90"][flipped*="vertical"][flipped*="horizontal"] .inline-image-info { top: auto; bottom: 0px; left: -100%; right: auto; .origin(bottom, right); .transform(-90deg, -1, -1); } .image[orientation="180"][flipped*="vertical"][flipped*="horizontal"] .inline-image-info { top: auto; bottom: 0px; left: auto; right: auto; .origin(bottom, right); .transform(180deg, -1, -1); } .image[orientation="270"][flipped*="vertical"][flipped*="horizontal"] .inline-image-info { top: auto; bottom: 100%; left: auto; right: auto; .origin(bottom, right); .transform(90deg, -1, -1); } /* XXX END */ .overlay-info { display: none; position: absolute; bottom: 0px; left: 0px; width: 100%; padding: 2px; padding-left: 10px; padding-right: 10px; box-sizing: border-box; background: black; color: white; opacity: 0.6; } .overlay-info:hover { .user-select(auto); } .overlay-info .float-right { float: right; } .overlay-info .secondary { font-style: italic; font-size: small; color: silver; } .overlay-info::selection, .overlay-info ::selection { color: white; background: red; } /*************************************************** Global status ***/ .global-status { display: block; opacity: 1; z-index: 1000; } /****************************************************** Indicators ***/ .up-indicator, .down-indicator, .start-indicator, .end-indicator, .top-indicator, .bottom-indicator { display: block; position: absolute; content: ""; top: 0px; left: 50%; height: 50px; width: 100px; margin-left: -50px; overflow: hidden; cursor: hand; } .up-indicator:after, .down-indicator:after { display: inline-block; position: absolute; content: ""; width: 50px; height: 50px; bottom: -25px; left: 25px; background: yellow; .rotate(45deg); } .down-indicator { top: auto; bottom: 0px; } .down-indicator:after { top: -25px; bottom: auto; } .start-indicator, .end-indicator { left: 0px; width: 10px; height: 100%; margin: 0px; background: yellow; } .end-indicator { left: auto; right: 0px; } .top-indicator, .bottom-indicator { left: 0px; height: 10px; width: 100%; margin: 0px; background: yellow; } .bottom-indicator { top: auto; bottom: 0px; } /* default state */ .up-indicator, .down-indicator, .start-indicator, .end-indicator, .top-indicator, .bottom-indicator { display: none; } /* these are generic containers for indicators */ .global-mode-indicators, .context-mode-indicators { position: absolute; height: 20px; width: auto; min-width: 300px; text-align: right; color: transparent; } .global-mode-indicators { top: 20px; right: 20px; } .context-mode-indicators { right: 20px; bottom: 20px; } .global-mode-indicators .mode-tip, .context-mode-indicators .mode-tip { display: none; opacity: 0.5; font-weight: bold; color: gray; } .global-mode-indicators:hover .mode-tip, .context-mode-indicators:hover .mode-tip { display: inline-block; } .global-mode-indicators > *, .context-mode-indicators > * { font-size: small; vertical-align: center; margin-left: 10px; } .global-mode-indicators .circle, .context-mode-indicators .circle { display: inline-block; width: @single-image-indicator-size; height: @single-image-indicator-size; border-radius: 50%; } /* hide indicators in single image mode */ .single-image-mode.viewer .global-mode-indicators { opacity: 0.5; } .light.single-image-mode.viewer .global-mode-indicators { opacity: 0.1; } .dark.single-image-mode.viewer .global-mode-indicators { opacity: 0.6; } .single-image-mode.viewer .global-mode-indicators:hover { opacity: 1; } /* actual indicators */ /* marks... */ .global-mode-indicators .marked-only-visible, .global-mode-indicators .marks-visible, .context-mode-indicators .current-image-marked { display: none; color: blue; height: 20px; vertical-align: center; } .global-mode-indicators .marked-only-visible .shown, .global-mode-indicators .marks-visible .shown, .context-mode-indicators .current-image-marked .shown { display: none; } .global-mode-indicators .marked-only-visible:after, .global-mode-indicators .marks-visible:after, .context-mode-indicators .current-image-marked:after { display: inline-block; width: 6px; height: 6px; border-radius: 50%; content: ""; background-color: blue; border: solid 2px blue; margin-left: 5px; margin-top: 3px; top: 50%; } .marks-visible.viewer .global-mode-indicators .marks-visible { display: inline-block; } .marked-only-view.viewer .global-mode-indicators .marks-visible { display: none; } .marked-only-view.viewer .global-mode-indicators .marked-only-visible { display: inline-block; } .marked-only-view.viewer:not(.marks-visible) .global-mode-indicators .marked-only-visible:after { background-color: transparent; } /* image mark in single image mode... */ .context-mode-indicators .current-image-marked { display: none; color: blue; } .single-image-mode.marks-visible.viewer .context-mode-indicators .current-image-marked.shown { display: inline-block; } /********************************************** Mode: single image ***/ .single-image-mode.viewer .image { background-color: transparent; /* NOTE: need to keep a distance from screen borders... */ border: solid transparent 2px; } .single-image-mode.viewer .image:not(.current) { /* XXX for some reason this breaks the alignment on large magnifications... display: none; */ /* XXX this makes images pass through the :visible filter... opacity: 0; */ visibility: hidden; } /********************************************************** Themes ***/ /* XXX this is by no means final... */ .viewer, .light.viewer, .light.viewer .overlay-block .background { background: white; } .gray.viewer, .gray.viewer .overlay-block .background { background: #333; } .dark.viewer, .dark.viewer .overlay-block .background { background: #0a0a0a; } /********************************************************* Overlay ***/ .overlay-block { display: none; position: absolute: top: 0px; left: 0px; height: 100%; width: 100%; } .viewer.overlay .overlay-block { display: block; } .overlay-block .content { } .overlay-block .background { position: absolute: top: 0px; left: 0px; height: 100%; width: 100%; opacity: 0.7; } /************************************************************ Help ***/ /* XXX make this more generic, and not just for the keyboard... */ /* this is for sliding stuff */ .viewer.drawer-mode { box-shadow: 0px 0px 50px 0px silver; } /* help */ .keyboard-help { width: 80%; margin-top: 20px; margin-left: 15%; margin-right: 5%; margin-bottom: 100px; } .keyboard-help .section-doc { font-size: small; vertical-align: top; font-style: italic; } .keyboard-help th { text-align: left; height: 50px; vertical-align: bottom; border-bottom: solid gray 1px; } .keyboard-help tr:hover { background: #eee; vertical-align: top; } .keyboard-help tr td:first-child { color: gray; font-style: italic; padding-right: 20px; padding-left: 10px; } .keyboard-help .section-doc td:only-child { padding-right: 0px; padding-left: 0px; } /********************************************************************** * vim:set spell ft=css : */