New REM client: REM-Client 5776589, 64-bit (equipment dealer by hardpoint - what sits on each, the hold apart, hold bar and credits in the tabs row; base nav bar in the maneuver bar's look with the room's services in a second row; a double click runs a row's main action; a room change closes the open windows; the repair window's first click repairs, no second payment)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-06 08:10:15 +01:00
co-authored by Claude Opus 5.5
parent 21626edb8e
commit b7abd01dfd
35 changed files with 69 additions and 29 deletions
+1 -1
View File
@@ -30,7 +30,7 @@
<div class="cols">
<div class="savelist">
<div class="hint" style="padding: 12dp;" data-if="saves.size == 0">No saved games.</div>
<div class="sv" data-for="s : saves" data-class-sel="s.selected" data-action="pick" data-attr-data-arg="s.key">
<div class="sv" data-for="s : saves" data-class-sel="s.selected" data-action="pick" data-dbl="open" data-attr-data-arg="s.key">
<span class="n">{{ s.name }}</span><span class="t">{{ s.time }}</span>
</div>
</div>
+1 -1
View File
@@ -30,7 +30,7 @@
<div class="head"><span class="c1">Name</span><span class="c2">Saved</span></div>
<div class="body">
<div class="empty" data-if="saves.size == 0">No saved games.</div>
<div class="row" data-for="s : saves" data-class-selected="s.selected" data-action="pick" data-attr-data-arg="s.key">
<div class="row" data-for="s : saves" data-class-selected="s.selected" data-action="pick" data-dbl="open" data-attr-data-arg="s.key">
<span class="c1">{{ s.name }}</span><span class="c2">{{ s.time }}</span>
</div>
</div>
+1 -1
View File
@@ -48,7 +48,7 @@
<div class="colm side">
<h3 style="margin-bottom: 8dp;">Offers</h3>
<div class="list">
<div class="offer" data-for="o : offers" data-class-selected="o.selected" data-action="pick" data-attr-data-arg="o.key">
<div class="offer" data-for="o : offers" data-class-selected="o.selected" data-action="pick" data-dbl="accept" data-attr-data-arg="o.key">
<img data-attr-src="o.icon"/>
<div class="mid"><div class="t">{{ o.title }}</div><div class="d">{{ o.text }}</div></div>
<span class="r">{{ o.reward }}</span>
+20 -14
View File
@@ -11,23 +11,28 @@
top: 4dp;
width: auto;
transform: translateX(-50%);
display: block;
display: flex;
flex-direction: column;
align-items: center;
background-color: transparent;
}
/* in the flight HUD's design: one frame with cut corners (rem.rcss, hudframes), no box per button */
.navbar { display: flex; flex-direction: row; align-items: center; height: 48dp; box-sizing: border-box; padding: 0 18dp; decorator: ninepatch(fb, fb-i); }
.nb { display: flex; flex-direction: row; align-items: center; height: 36dp; padding: 0 12dp 0 8dp; margin: 0 1dp; border-radius: 3dp; }
.nb:hover { background-color: #5cc8f01a; }
/* in the flight HUD's design, as its maneuver bar (hud.rml .mans): one frame with cut corners
(rem.rcss, hudframes), icon over its name, a thin line between, the active one amber */
.navbar { display: flex; flex-direction: row; align-items: center; height: 76dp; box-sizing: border-box; padding: 0 18dp; decorator: ninepatch(fb, fb-i); }
.nb { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 84dp; height: 62dp; padding: 0 10dp; border-left: 1dp #2b6f9e; }
.nb:first-child, .nb.active { border-left-width: 0; }
.nb:hover { background-color: #f2b13c14; }
.nb.active { background-color: #f2b13c1f; }
.nb.disabled { opacity: 0.4; }
.nb.disabled { opacity: 0.35; }
.nb.disabled:hover { background-color: transparent; }
.nb img { width: 28dp; height: 28dp; margin-right: 6dp; }
.nb span { font-family: "Saira SemiCondensed"; font-weight: 600; font-size: 13dp; letter-spacing: 1.5dp; text-transform: uppercase; color: #e8f4ff; }
.nb img { width: 34dp; height: 34dp; }
.nb:hover img, .nb.active img { image-color: #f2b13c; }
.nb span { margin-top: 2dp; font-family: "Saira SemiCondensed"; font-weight: 600; font-size: 12dp; letter-spacing: 1dp; text-transform: uppercase; white-space: nowrap; color: #b9d4ea; }
.nb.active span { color: #f2b13c; }
.nb:hover span { color: #5cc8f0; }
.nb.tab img { width: 22dp; height: 22dp; }
.nb.tab span { font-size: 12dp; color: #b9d4ea; }
.sep { width: 1dp; height: 28dp; background-color: #2b6f9e; margin: 0 8dp; }
/* the room's services (repair, launch, the dealer's desk, ...) in a smaller second row under it */
.navbar.tabs { height: 56dp; margin-top: 4dp; padding: 0 14dp; }
.tabs .nb { min-width: 72dp; height: 46dp; }
.tabs .nb img { width: 26dp; height: 26dp; }
</style>
</head>
<body class="navstrip" data-model="navbar">
@@ -35,8 +40,9 @@
<div class="nb" data-for="b : rooms" data-class-active="b.active" data-class-disabled="b.disabled" data-action="click" data-attr-data-arg="b.key">
<img data-if="b.icon != ''" data-attr-src="b.icon"/><span>{{ b.label }}</span>
</div>
<div class="sep" data-if="tabs.size &gt; 0"></div>
<div class="nb tab" data-for="b : tabs" data-class-active="b.active" data-class-disabled="b.disabled" data-action="click" data-attr-data-arg="b.key">
</div>
<div class="navbar tabs" data-if="shown && tabs.size &gt; 0">
<div class="nb" data-for="b : tabs" data-class-active="b.active" data-class-disabled="b.disabled" data-action="click" data-attr-data-arg="b.key">
<img data-if="b.icon != ''" data-attr-src="b.icon"/><span>{{ b.label }}</span>
</div>
</div>
+40 -6
View File
@@ -59,6 +59,27 @@
.panel .pfoot { display: flex; flex-direction: row; margin-top: 10dp; }
.panel .pfoot .btn { margin: 0 8dp 0 0; padding: 3dp 10dp; }
.content { position: relative; }
/* hold and credits in the tabs' row, large: the hold a bar that fills with the load, amber from 3/4, red full */
.stat { display: flex; flex-direction: row; align-items: center; align-self: center; margin-left: 24dp; }
.stat .sk { margin-right: 10dp; font-family: "Saira SemiCondensed"; font-weight: 600; font-size: 12dp; letter-spacing: 2dp; color: #8197ad; }
.stat .sv { font-family: "IBM Plex Mono"; font-size: 20dp; color: #f2b13c; }
.hbar { position: relative; width: 200dp; height: 24dp; border: 1dp #2b6f9e; background-color: #00000066; }
.hbar .hf { position: absolute; left: 0; top: 0; bottom: 0; background-color: #3a8fc899; }
.hbar .hf.warn { background-color: #f2b13c99; }
.hbar .hf.bad { background-color: #ef6a5bcc; }
.hbar .ht { position: relative; display: block; line-height: 24dp; text-align: center; font-family: "IBM Plex Mono"; font-size: 15dp; color: #e8f4ff; }
/* your equipment in three parts: the ship's hardpoints (what sits on each, the empty ones dim), what is
mounted without a hardpoint, the hold -- not mounted, an amber edge */
.sec { display: flex; flex-direction: row; align-items: center; margin: 12dp 0 4dp 0; padding-bottom: 3dp; border-bottom: 1dp #2b6f9e; font-family: "Saira SemiCondensed"; font-weight: 600; font-size: 12dp; letter-spacing: 2dp; color: #5cc8f0; }
.sec:first-child { margin-top: 0; }
.sec .cnt { margin-left: auto; font-family: "IBM Plex Mono"; font-weight: 400; letter-spacing: 0; color: #8197ad; }
.sec.held { color: #f2b13c; border-bottom-color: #f2b13c66; }
.good .slot { font-family: "Saira SemiCondensed"; font-weight: 600; font-size: 10dp; letter-spacing: 1dp; text-transform: uppercase; white-space: nowrap; color: #8fb3d0; }
.good.empty .n { color: #5c7a94; }
.good.empty .txt { margin-left: 40dp; } /* in line with the rows that have an icon (30 + 10 dp) */
.good.held { border-left-color: #f2b13c66; }
.good.held.selected { border-left-color: #f2b13c; }
.good.held .note { color: #5fd08a; }
</style>
</head>
<body class="window" data-model="outfitter">
@@ -66,8 +87,6 @@
<img class="head-ico" src="3db:INTERFACE/REM/IMAGES/icon_ships.3db"/>
<span class="title">EQUIPMENT DEALER</span><span class="sl">\\\</span>
<span class="spacer"></span>
<span class="chip">Hold <span class="v">{{ hold }}</span></span>
<span class="chip">Credits <span class="v">{{ credits }}</span></span>
<span class="chip" data-if="tax != ''">{{ tax }}<div class="tip">The server takes this share of what you sell to the base. It follows the region's trade of the last days: the busiest region pays the most.</div></span>
<span class="close" data-action="close">&#215;</span>
</div>
@@ -79,6 +98,8 @@
<div class="tab" data-class-active="category == 1" data-action="category" data-arg="1">Ammo</div>
<div class="tab" data-class-active="category == 2" data-action="category" data-arg="2">Equipment</div>
<div class="tab" data-class-active="category == 3" data-action="category" data-arg="3">Cargo bay</div>
<div class="stat" style="margin-left: auto;"><span class="sk">HOLD</span><div class="hbar"><div class="hf" data-class-warn="hold_pct &gt;= 75" data-class-bad="hold_pct &gt;= 100" data-style-width="hold_pct + '%'"></div><span class="ht">{{ hold }}</span></div></div>
<div class="stat"><span class="sk">CREDITS</span><span class="sv">{{ credits }}</span></div>
</div>
<div class="split">
<div class="colm">
@@ -88,7 +109,7 @@
<input class="text search" type="text" data-value="filter" maxlength="40"/>
<div class="list">
<div class="hint" style="padding: 10dp;" data-if="market.size == 0">No equipment for sale here.</div>
<div class="good" data-for="r : market" data-class-selected="r.selected" data-class-disabled="r.disabled" data-action="buy-pick" data-attr-data-arg="r.key">
<div class="good" data-for="r : market" data-class-selected="r.selected" data-class-disabled="r.disabled" data-action="buy-pick" data-dbl="deal" data-attr-data-arg="r.key">
<img data-if="r.icon != ''" data-attr-src="r.icon"/>
<div class="txt"><div class="n">{{ r.name }}</div><div class="note" data-if="r.note != ''">{{ r.note }}</div></div>
<span class="p">{{ r.price }}</span>
@@ -113,10 +134,23 @@
</span>
</div>
<div class="list">
<div class="hint" style="padding: 10dp;" data-if="gear.size == 0">No equipment.</div>
<div class="good" data-for="r : gear" data-class-selected="r.selected" data-class-disabled="r.disabled" data-action="sell-pick" data-attr-data-arg="r.key">
<div class="sec" data-if="hps.size &gt; 0">HARDPOINTS<span class="cnt">{{ hp_used }} / {{ hps.size }}</span></div>
<div class="good" data-for="r : hps" data-class-empty="r.key == ''" data-class-selected="r.selected" data-class-disabled="r.disabled" data-action="sell-pick" data-dbl="deal" data-attr-data-arg="r.key">
<img data-if="r.icon != ''" data-attr-src="r.icon"/>
<div class="txt"><div class="n">{{ r.name }}</div><div class="note">{{ r.note }}</div></div>
<div class="txt"><div class="n">{{ r.key == '' ? 'empty' : r.name }}</div><div class="slot">{{ r.slot }}</div></div>
<span class="p">{{ r.price }}</span>
</div>
<div class="sec" data-if="inside.size &gt; 0">MOUNTED, NO HARDPOINT</div>
<div class="good" data-for="r : inside" data-class-selected="r.selected" data-class-disabled="r.disabled" data-action="sell-pick" data-dbl="deal" data-attr-data-arg="r.key">
<img data-if="r.icon != ''" data-attr-src="r.icon"/>
<div class="txt"><div class="n">{{ r.name }}</div></div>
<span class="c">{{ r.count }}</span><span class="p">{{ r.price }}</span>
</div>
<div class="sec held">CARGO HOLD &#183; NOT MOUNTED<span class="cnt">{{ hold }}</span></div>
<div class="hint" style="padding: 10dp;" data-if="gear.size == 0">Nothing in the hold.</div>
<div class="good held" data-for="r : gear" data-class-selected="r.selected" data-class-disabled="r.disabled" data-action="sell-pick" data-dbl="deal" data-attr-data-arg="r.key">
<img data-if="r.icon != ''" data-attr-src="r.icon"/>
<div class="txt"><div class="n">{{ r.name }}</div><div class="note" data-if="r.note != ''">{{ r.note }}</div></div>
<span class="c">{{ r.count }}</span><span class="p">{{ r.price }}</span>
</div>
</div>
+2 -2
View File
@@ -18,7 +18,7 @@
.sum { display: flex; flex-direction: row; align-items: center; border-top: 1dp #24405c; padding-top: 12dp; margin-top: 8dp; }
.sum .k { font-family: "Saira SemiCondensed"; letter-spacing: 1.1dp; text-transform: uppercase; color: #8197ad; margin-right: 10dp; }
.sum .v { font-family: "IBM Plex Mono"; font-size: 20dp; color: #f2b13c; margin-right: 24dp; }
.sum .btn { margin: 0 0 0 auto; }
.go { margin: 12dp 0 0 0; padding: 10dp 16dp; text-align: center; font-size: 16dp; } /* the whole width under the total */
.warn { color: #ef6a5b; margin-right: 14dp; }
</style>
</head>
@@ -50,8 +50,8 @@
<div class="sum">
<span class="k">Total</span><span class="v">{{ total }}</span>
<span class="warn" data-if="too_much">Not enough credits</span>
<div class="btn primary" data-class-disabled="too_much || nothing" data-action="repair">Repair<div class="tip">Repairs the checked parts and pays the total.</div></div>
</div>
<div class="btn primary go" data-class-disabled="too_much || nothing" data-action="repair">Repair<div class="tip">Repairs the checked parts and pays the total.</div></div>
</div>
</div>
</div>
+1 -1
View File
@@ -101,7 +101,7 @@
</div>
<div class="grid">
<div class="hint" data-if="cards.size == 0">{{ empty }}</div>
<div class="icard" data-for="c : cards" data-class-selected="c.selected" data-class-out="c.out" data-action="pick" data-attr-data-arg="c.key">
<div class="icard" data-for="c : cards" data-class-selected="c.selected" data-class-out="c.out" data-action="pick" data-dbl="add" data-attr-data-arg="c.key">
<span class="q" data-if="c.qty != ''">{{ c.qty }}</span>
<span class="badge" data-if="c.badge != ''">{{ c.badge }}</span>
<img class="star" data-if="c.featured" src="3db:INTERFACE/REM/IMAGES/stat_rating_icon.3db"/>
+1 -1
View File
@@ -17,7 +17,7 @@
}
/* the rollover help ("Click on a character ..."): centred under the nav bar at the top, in the
flight HUD's frame -- not at the classic point, where it lay over the nav bar */
.ftip.roll { left: 50%; top: 58dp; transform: translateX(-50%); max-width: 640dp; padding: 8dp 20dp; font-size: 14dp; text-align: center; white-space: pre-line; }
.ftip.roll { left: 50%; top: 144dp; transform: translateX(-50%); max-width: 640dp; padding: 8dp 20dp; font-size: 14dp; text-align: center; white-space: pre-line; }
/* a REM window's .tip (the hovered element's), drawn here so no other window covers it */
.ftip.hov { width: 260dp; white-space: normal; font-family: Barlow; }
</style>
+2 -2
View File
@@ -48,7 +48,7 @@
<input class="text search" type="text" data-value="filter" maxlength="40"/>
<div class="list">
<div class="empty hint" style="padding: 10dp;" data-if="market.size == 0">Nothing for sale here.</div>
<div class="good" data-for="r : market" data-class-selected="r.selected" data-action="buy-pick" data-attr-data-arg="r.key">
<div class="good" data-for="r : market" data-class-selected="r.selected" data-action="buy-pick" data-dbl="deal" data-attr-data-arg="r.key">
<img data-if="r.icon != ''" data-attr-src="r.icon"/><span class="n">{{ r.name }}</span><span class="c">{{ r.count }}</span><span class="p">{{ r.price }}</span>
</div>
</div>
@@ -57,7 +57,7 @@
<div class="col-h"><h3>Your cargo</h3><span class="hint">hold {{ hold }}</span></div>
<div class="list">
<div class="empty hint" style="padding: 10dp;" data-if="cargo.size == 0">Your hold carries no goods.</div>
<div class="good" data-for="r : cargo" data-class-selected="r.selected" data-class-disabled="r.disabled" data-action="sell-pick" data-attr-data-arg="r.key">
<div class="good" data-for="r : cargo" data-class-selected="r.selected" data-class-disabled="r.disabled" data-action="sell-pick" data-dbl="deal" data-attr-data-arg="r.key">
<img data-if="r.icon != ''" data-attr-src="r.icon"/><span class="n">{{ r.name }}</span><span class="note">{{ r.note }}</span><span class="c">{{ r.count }}</span><span class="p">{{ r.price }}</span>
</div>
</div>